• 关于

    数据缓冲什么意思

    的搜索结果

回答

Re数据库诊断报告中的“其它数据空间”是什么意思呢? 感谢TK的回答[ 处理意见 ] 您好,其它数据空间指的是mysql数据库的系统空间,包括事务日志文件(redo log)以及ibdata空间(包括InnoDB表的元数据信息,undo回滚段,doublewrite buffer双写缓冲),这部分空间占用3G左右,这是正常的,所有的RDS实例这部分空间都是占用3G左右。

八零杂音 2019-12-02 00:13:08 0 浏览量 回答数 0

问题

在我的例子里,Linux的kernel与user space如何进行通信才好?

杨冬芳 2019-12-01 20:21:09 1022 浏览量 回答数 2

问题

关于mina的setSendBufferSize奇怪之旅 400 请求报错

kun坤 2020-05-29 11:00:09 2 浏览量 回答数 1

Quick BI 数据可视化分析平台

2020年入选全球Gartner ABI魔力象限,为中国首个且唯一入选BI产品

回答

听起来像是个服务器推送消息的功能######可以这么想啊。###### controller调用TCP的同时锁住当前线程,TCP返回后解锁当前线程,不要忘记处理超时。 整个过程会很麻烦,建议写成公共Service,加锁和解锁在Service中完成。 ######回复 @bBugyang : 就是阻塞线程######锁是用什么锁啊。让线程睡眠?还是。。。###### 我觉得你和前端的ajax整合在一起更好。 不过还是要看你的具体需求。 我们对这样的数据都走AJAX ######回复 @bBugyang : 你的正常流程还继续走。 有异步要处理的数据。 你放到一个单独的方法里。ajax去请求你的特殊长时间方法。 ajax本身就是异步处理。你就可以耐心的去等待数据显示了。######技术有限啊。。。######数据请求到controller 再请求tcp 直接开个线程 复杂点中间加个队列做缓冲######是直接开个线程去请求tcp吗?~######用阻塞式不就好了?######什么意思呢?。###### 感觉这个问题跟JFinal无关呢~  可以到其他节点问问看。同关注答案~ ######对,我也觉得和jfinal无关了。。因为之前考虑是jfinal封装了servlet等。。servlet3.0是提供异步的,不知道封装了没有,所以会这么问。######确实无关######上代码吧骚年######写个后台线程,定期通过tcp从另外一台服务器拿回消息,然后放在数据库里,jfinal访问是就直接从数据库里拿了。######google java Exchanger######Servlet 3支持async servlet,至于JFinal支不支持说不清楚。

kun坤 2020-05-29 11:37:46 0 浏览量 回答数 0

回答

引用来自“chentian08”的答案 引用来自“中山野鬼”的答案 引用来自“Jack.arain”的答案 MP3一般是1152个采样为一帧来编码的,知道采样率,声道,很容易计算出1秒多少帧。一般音频播放缓冲搞个1秒左右就够了。 单纯解码mp3也可以试试  mpg123。。。 貌似楼主这些概念还没有。哈。我到现在还不清楚,为什么他是做解码,而从数据流中取了 1024 * 24bits。 刚接接触这方面的知识,确实不太了解,你有这方面的学习资料或例子什么的,能不能发点给我或者加我QQ:735838956@qq.com。其实我的目的就是,想做个拥有MP3播放器功能的东西,然后又跟网络有点关系,想实现的功能主要有:本地MP3文件的播放,这个有很多方法,但是具体怎么实现,我真的想知道,我就是想在发送数据的时候,同时把它播放出来,结果就出现了上面提到的问题了; 发送MP3文件,这个应该就是先读取一个大小,再发送; 接收MP3数据,然后播放,这个应该就是接受到数据后,解码播放; 我 00年搞AC3 DSP算法优化时,碰过音频,后来就没碰了。你要看资料,先看标准吧。标准理解清楚还是必要的。如果标准中很多俗语或名词搞不清楚,那你还需要补充知识。 ######回调函数用用还是应该的。应该是回调机制没处理好。需要有定时器。指定时间间隔,处理,填BUF。另一种可能,源码有BUG,如果源码没问题,不会占用那么高的CPU。音频解码占用的计算资源很少的。 ###### 引用来自“中山野鬼”的答案 回调函数用用还是应该的。应该是回调机制没处理好。需要有定时器。指定时间间隔,处理,填BUF。另一种可能,源码有BUG,如果源码没问题,不会占用那么高的CPU。音频解码占用的计算资源很少的。 如果是你,你会怎么做,因为这些音频数据还要通过网络发出,除了一帧帧地读,我想不出其它办法,刚接触音频开发,请指点。 ###### 引用来自“chentian08”的答案 引用来自“中山野鬼”的答案 回调函数用用还是应该的。应该是回调机制没处理好。需要有定时器。指定时间间隔,处理,填BUF。另一种可能,源码有BUG,如果源码没问题,不会占用那么高的CPU。音频解码占用的计算资源很少的。 如果是你,你会怎么做,因为这些音频数据还要通过网络发出,除了一帧帧地读,我想不出其它办法,刚接触音频开发,请指点。 应该是网络接入吧。如果是网络发送自然是编码后数据,不会是PCM数据。不过从你的描述很奇怪。只有PCM数据才需要 24bits,1024作为一个block,已备频域处理。 如果是我做,至少开1s的解码BUF。无非是采样率最多X4个bytes。你觉得大吗?哈。 ###### 引用来自“中山野鬼”的答案 引用来自“chentian08”的答案 引用来自“中山野鬼”的答案 回调函数用用还是应该的。应该是回调机制没处理好。需要有定时器。指定时间间隔,处理,填BUF。另一种可能,源码有BUG,如果源码没问题,不会占用那么高的CPU。音频解码占用的计算资源很少的。 如果是你,你会怎么做,因为这些音频数据还要通过网络发出,除了一帧帧地读,我想不出其它办法,刚接触音频开发,请指点。 应该是网络接入吧。如果是网络发送自然是编码后数据,不会是PCM数据。不过从你的描述很奇怪。只有PCM数据才需要 24bits,1024作为一个block,已备频域处理。 如果是我做,至少开1s的解码BUF。无非是采样率最多X4个bytes。你觉得大吗?哈。 什么叫1s的解码BUF。1s是什么意思? ###### 引用来自“chentian08”的答案 引用来自“中山野鬼”的答案 引用来自“chentian08”的答案 引用来自“中山野鬼”的答案 回调函数用用还是应该的。应该是回调机制没处理好。需要有定时器。指定时间间隔,处理,填BUF。另一种可能,源码有BUG,如果源码没问题,不会占用那么高的CPU。音频解码占用的计算资源很少的。 如果是你,你会怎么做,因为这些音频数据还要通过网络发出,除了一帧帧地读,我想不出其它办法,刚接触音频开发,请指点。 应该是网络接入吧。如果是网络发送自然是编码后数据,不会是PCM数据。不过从你的描述很奇怪。只有PCM数据才需要 24bits,1024作为一个block,已备频域处理。 如果是我做,至少开1s的解码BUF。无非是采样率最多X4个bytes。你觉得大吗?哈。 什么叫1s的解码BUF。1s是什么意思? 1s==1秒钟。后面我已经给出公式了。采样率 X 4 bytes。当然这是一个通道的容量。 ###### MP3一般是1152个采样为一帧来编码的,知道采样率,声道,很容易计算出1秒多少帧。一般音频播放缓冲搞个1秒左右就够了。 单纯解码mp3也可以试试  mpg123。。。######        99%是代码或者做法有bug. 这种任务量感觉非常的少. 应该被秒杀才对.  现在的CPU很霸气的. 给逻辑的每一步加时间输出,  定位耗时点.###### 引用来自“Jack.arain”的答案 MP3一般是1152个采样为一帧来编码的,知道采样率,声道,很容易计算出1秒多少帧。一般音频播放缓冲搞个1秒左右就够了。 单纯解码mp3也可以试试  mpg123。。。 貌似楼主这些概念还没有。哈。我到现在还不清楚,为什么他是做解码,而从数据流中取了 1024 * 24bits。 ###### 引用来自“中山野鬼”的答案 引用来自“Jack.arain”的答案 MP3一般是1152个采样为一帧来编码的,知道采样率,声道,很容易计算出1秒多少帧。一般音频播放缓冲搞个1秒左右就够了。 单纯解码mp3也可以试试  mpg123。。。 貌似楼主这些概念还没有。哈。我到现在还不清楚,为什么他是做解码,而从数据流中取了 1024 * 24bits。 刚接接触这方面的知识,确实不太了解,你有这方面的学习资料或例子什么的,能不能发点给我或者加我QQ:735838956@qq.com。其实我的目的就是,想做个拥有MP3播放器功能的东西,然后又跟网络有点关系,想实现的功能主要有:本地MP3文件的播放,这个有很多方法,但是具体怎么实现,我真的想知道,我就是想在发送数据的时候,同时把它播放出来,结果就出现了上面提到的问题了; 发送MP3文件,这个应该就是先读取一个大小,再发送; 接收MP3数据,然后播放,这个应该就是接受到数据后,解码播放;

kun坤 2020-06-06 23:55:47 0 浏览量 回答数 0

回答

硬盘读写速度现在怎么都达不到千兆, ssd读也达不到。(特殊设备除外,貌似看到新闻说有实验室的产品读写速度可以过G) 不过可以采取,写入缓冲的方式,数据先保存在内存,再写入到硬盘,不过缺点怕掉电。 读的话,采取分布式的读,可以达到很高的吞吐量。 网络传输的话,问题在于怎么保证传输稳定和不出错######这对内存的要求很高啊,而且还不能耽误其他程序对内存的使用,这个内存我觉得应该很大吧###### 引用来自“十一文”的答案 硬盘读写速度现在怎么都达不到千兆, ssd读也达不到。(特殊设备除外,貌似看到新闻说有实验室的产品读写速度可以过G) 不过可以采取,写入缓冲的方式,数据先保存在内存,再写入到硬盘,不过缺点怕掉电。 读的话,采取分布式的读,可以达到很高的吞吐量。 网络传输的话,问题在于怎么保证传输稳定和不出错 这么说来, 在顺序存取方面 , 网络传输速度相对与硬盘 io 速度还是有优势的,不知道这么理解是否成立。 因为机放内部设备间千兆网卡很常见,传输速度相当快,并且成本相对硬盘少许多。 ######看贴不跟帖,帖子要沉了。需要顶。 无论对错。发表点个人观点也好。不能让它沉。 ###### "千兆网卡很常见", 這裡 “ 千兆” 是指1000M bits, 大概也就100M Bytes。 Intel SSD 520 Sequential Read 已经可高达550M Bytes per second, 顺序写可高达275M Bytes per second.######回复 @十一文 : 现在的HBA卡4G的已经很通用了,好像12G的都出来了,一般服务器都有好几个接口的,再来个负载均很啥的,网络传输不是问题######汗 查了哈 还真是这样。擦我out了!######网络允许帮定双网卡。所以,网络传输可以更快点,相对来说,速度提升技术性难度小点。 磁盘阵列是否回更好? 光线通讯用的网卡是否会更快点。 ###### 顺便提点应用。 是这样的, 排序在信息处理方面很常见。 无论用什么算法。都是在一个相对平等的环境中。 现实中应用,比如1g内容的排序和1T内容排序难点还是数据交换上。 1g可以全部加载进内存玩。1T就要涉及到信息交换了。如果一个系统界面,把存储信息部分扩展到近乎无限空间大小。 就好比内存数据交换比磁盘数据交换要快许多。 比如1T大小数据做排序。 只要一个设备顺序读取数据,按照开头部分把数据通过网络分发给N 台机器,处理除了开头部分数据,后面的数据排序。这样就可以N多设备协同工作。效率达到 1+1 > 2 的目的。 否则如果是1台设备需要 加载数据,排序, 临时存储, 加载另外数据,处理,临时存储,加载.... 汇总分结果,获得总结果。 1台设备这么处理,做了很多重复劳动。如果网络够快 多台设备 避免了重复加载。 达到 1+1>2######回复 @十一文 : 差不多的意思。######hadoop是把数据分成分成多个部分,每部分各自处理结果,然后汇总处理。即把你的1t的数据分成n份,然后每份分发给不同机器处理。然后汇总结果。不知道适用你的场景不?######貌似这中数据分析,现在流行用hadoop。楼主可以调研哈######这么说不好理解。形象一点说一下:假设有1000个数据样本,每个样本里有1T条数据内容。 一知每个样本内数据条目重复率为0.001%.目的,找出这1000个样本内,每个样本中重复的样本。并统计所有样本中重复的次数。 这个如果算复杂运算,不如说是大数据处理。 假设 每个设备 一次能加载1G条数据。######硬盘技术感觉好多年都在原地踏步没有质的飞跃啊###### @johnzhang68 毕竟转速有影响######磁性硬盘在容量方面还是有明显的飞跃。速度方面提高得慢一些。######或许未来,存储虚拟化是条路子。  数据处理和数据交互关系密切。 以数据处理为目的,建立多系统群集方式在处理上或许会比高计算系统群集更有优势。 ######又没落了。顶起 ######没有试过,关注一下######再看了哈貌似你真的很需要hadoop

kun坤 2020-06-07 22:18:40 0 浏览量 回答数 0

回答

更换服务器~100个是单服务器最大的负荷了你用的是镶嵌式的,要选择服务器机组的那种~刀片式服务器~然后oracl数据库支持分开安装。同步处理~ 你肯定买的是架式服务器~######装ORACLE服务器是刀片式的,6核至强 24G的内存 应该不是服务器瓶颈######oracl装在独立的一台服务器上的话,只支持小形企业和地、市级企业运行 你说的情况,可以理解你的数据量非常庞大,,有可能是省、国家级的数据量了~~ 让你单位给你单独开个服务器房间,更换服务器机柜然后购买刀片式服务器做服务器阵列机组~######数据量倒不会太大,一天1G不到,问题是很多存储过程的逻辑很复杂,一条线程调用存储过程,要等待很久才会返回,直接导致工作线程速度很慢,数据进入速度太快,工作异常状态频繁出现。######必须要实时的存入数据库吗?不能先缓存到服务器,然后让服务器慢慢去处理吗?或者直接将数据记入日志,然后sqlload?######回复 @xinzaibing : 我想到一个蛋疼的方式:数据写文件,文件内容定期入库,程序定期读取数据库计算的结果缓存到内存中。不知道你具体需求,瞎琢磨一个。######回复 @asdfsx : 公司领导一致认为内存不可靠,断电、程序异常什么的...存在内存的数据就没了...真是蛋疼啊######回复 @xinzaibing : 如果数据量不大的话,还有一个方案就是都保存在内存里,然后定时把内存里的结果同步到数据库里。数据库的逻辑挪到程序里..........这个方案比较累啊。另外就是缓存可以加个优先级高低的判断。######目前要求是必须要实时入库,采取写日志文件的方法也可以。 这些数据有一个特点,在某一个时刻会有一个突然出现的峰值,然后又慢慢变少,但是这个时间是不固定的,由于只实用了一条双缓冲队列,所有需要紧急处理的数据和非紧急处理的数据都在队列里,而如果遇到非紧急数据,处理了很长的时间,就直接导致后面的紧急数据失效了...或者导致嵌入式程序判断服务端未收到数据,进而采取重发,导致一条队列里有非常多重复的数据。######我可能会使用数据写入日志文件,然后定时将日志入库的办法操作######大概意思可能是多线程对数据库表的操作导致数据表锁定,性能损失在内耗上了。。那数据表采用行级锁呢?(这样会增大系统开销)我是菜鸟,求教  ######回复 @xinzaibing : 这个应该是属于最初的设计问题,hohoho######回复 @asdfsx : 目前我也在往这方面考虑,如果数据分类处理。那就得大改结构了...唉######回复 @xinzaibing : 建议根据上传的不同数据进行不同的处理,不要一股脑的都放在缓存中,如果是心跳的话,应该立即响应,如果是要处理的数据的话,才需要进行缓存等待处理######ORACLE默认就是行级锁的应该.. 主要是数据的写入速度远远小于数据上传的速度,导致了缓存溢出,紧急数据不能得到及时处理,大量数据出现超时失效,无法对嵌入式的采集器程序作出及时的心跳相应和其他回复(因为都在队列中,无法处理,无心跳的话嵌入式采集器会误认为服务器断线)。最终导致单台服务器接入数据的嵌入式设备的数量太少,不满足需求。######去年刚毕业,由于公司小,一个人搞后台,压力太大啊...大家指指招呗~ @中山野鬼######今天到图书馆看了一本书《让Orcale跑的更快点》,上面说可以从如下几个方面优化: 数据库方面:建适当的索引,固定长度;查询条件比较尽量简化;不同的表放在不同的磁盘里…… 服务层:增大缓存,(有没有数据库连接池不知道你能用上不) 软件层:对Java使用PaperStatement 囫囵吞枣就记得这么多了。。。哭~~######非常感谢...我去看看这本书 :)######我不清楚你的数据采集的内容是什么。不过看的出,对实时性要求高。换我,基本上就一个思路。 1、做个前段服务器,什么事情都不干,只进行数据的压缩。然后所有数据库和计算操作,放到后端。 至于并发,你这种 1W=100台服务器的方式治标不治本。######@中山野鬼 是说对数据进行预处理,提取有效内容?还是就是zip?######回复 @asdfsx : 不一样的。而是数据压缩。采样数据中间,信息密度不会太大的。######老鬼的思路有点像我说的那个数据写日志文件,或者内存缓存定时入库...........都被否定了啊######@xinzaibing 还有一个建议,上传的数据加一个验证,如果上传的数据已经插入缓存,就不要再次插入了。无脑插入插到崩也不是什么好主意啊######回复 @asdfsx : 要回复的,要处理成功后才回复,存库失败或者某些异常导致服务端崩溃重启,就不进行回复,客户端会持续地进行重发,重发到一定次数后,存本地,等恢复正常后发送存本地的数据

kun坤 2020-06-09 11:56:38 0 浏览量 回答数 0

问题

【Java问答学堂】4期 如何保证消息的可靠性传输?(如何处理消息丢失的问题?)

剑曼红尘 2020-04-21 10:04:26 105 浏览量 回答数 2

回答

介绍了Amazon S3 使用的认证: http://dodomail.iteye.com/blog/1744389 ######这个很简单啊,把所有参数都做一次加密就是,秘钥你来生成授权给你的下游就是了,后台再做记录ip的的功能,这样谁请求你的API了就都知道了,自己实现也很快的######tokening,或者id这些加密,获取后再解密,密钥自己生成。就是加个验证的key值就可以吧,每次提交数据验证key的正确性###### 做一个认证服务,提供一个认证的webapi,用户先访问它获取token,然后拿着token去访问所有的webapi。每次接收到请求就拿着token找认证服务寻求验证。验证通过则papapa,不然就404。 你要说的是这种么?还是对访问做验证限制? ######回复 @devilsitan : 也是啊,那你再看看刚刚问的第二个问题######@liujiduo tomcat只是个web服务器。。不明白为什么和它要有关呢。。webapi又不是在tomcat上跑的。######回复 @devilsitan : 还有就是这种给webapi加token认证的方式,应该是我事先给某些指定的APP(比如我的iOS客户端或安卓客户端)发放私钥,然后它们根据私钥获取token。那如果我的网站前端通过ajax访问这些api是不是也需要通过token认证呢?如果是的话那不就会暴露出私钥了吗?先谢谢啦^_^######回复 @devilsitan : 那另一种 基于HTTP Digest认证的方式也是只用代码实现,不需要修改tomcat的配置吗?######@liujiduo 那这种和服务器就没多大关系了啥。。只要你有webapi服务在就行,什么访问都是通过HTTP来请求的。接口也很简单一个认证,一个验证。认证服务内部看你怎么设计,要么是简单的用户-权限,要么是用户-角色-权限,要么是带约束的用户-角色-权限,还有更加灵活的二者皆有,采取优先拒绝。###### 引用来自“devilsitan”的评论 做一个认证服务,提供一个认证的webapi,用户先访问它获取token,然后拿着token去访问所有的webapi。每次接收到请求就拿着token找认证服务寻求验证。验证通过则papapa,不然就404。 你要说的是这种么?还是对访问做验证限制? 肯定是要带Token的,访问还是用户名密码,认证通过cookie里存的就是用户名和token,token是有有效期的,过了有效期你就需要重新分配一个token。这个暴露问题,我也不知道肿么办,不过人家要存心搞你,这些还有用么。你看Digest还不是私钥放在cookie里,虽然用算法加密一次和服务器比对,人家只需要截下你的包,把加密后的验证字符拿去验证就是了。我没看出什么区别######回复 @liujiduo : 可以参考上面的那位给的亚马逊s3的rest api认证。也可以看下openstack的keystone的验证模式。都是一个令牌,就看你怎么用和。简单的就是我前面说的那样,复杂的更安全的就是他们那样。######明白了,谢谢!###### 顶 ######ajax的时候检测客户端用户权限不可以吗?###### Http Digest认证也就是防止重放攻击,如果是局域网项目感觉对认证的要求不用太高,主要还是网络安全和访问的监控和预警,要是互联网的觉得还是非对称签名比较安全,存粹算法决定。###### 引用来自“HandMU”的评论ajax的时候检测客户端用户权限不可以吗? 用户权限是跟用户绑定的,而客户端访问接口可能没有用户的概念,这样就不合适了啊######回复 @HandMU : 你没明白他意思,webapi,可能是非本系统用户######可参考open auth######回复 @liujiduo : 都会有基于用户权限检测的。你钻到死角了。######回复 @HandMU : 是啊,难道对于webapi的安全认证就没有一个好的办法么?不知道淘宝这些网站是怎么做的######ajax理论上还是post、get,依然带上所有你能使用的用户信息。###### 引用来自“刘敬伟”的评论 Http Digest认证也就是防止重放攻击,如果是局域网项目感觉对认证的要求不用太高,主要还是网络安全和访问的监控和预警,要是互联网的觉得还是非对称签名比较安全,存粹算法决定。 不是局域网项目,我是想让某些数据敏感的接口只能被已授权的客户端访问,而不是让别人只要知道了url就能恶意请求和操纵我的接口,我查了Http Basic和Http Digest的认证流程,但就是不清楚怎么应用到项目中来。######我觉得你的思路有点混乱,没搞清楚到底认证什么,怎么认证,认证力度如何。这些都要根据你的网络环境、服务器系统、还有你处理的数据类型有关系。如果不想用第三方安全策略,我建议采用非对称的安全算法,针对用户信息最签名和验证。在这个基础上对你接口接收的用户请求进行监控,如果有必要的话你接收的数据要进行过滤,就像支付宝也不是实时到账,中间肯定有一个审核数据的再次分发的缓冲处理机制。

kun坤 2020-06-02 15:55:28 0 浏览量 回答数 0

回答

" 介绍了Amazon S3 使用的认证: http://dodomail.iteye.com/blog/1744389 ######这个很简单啊,把所有参数都做一次加密就是,秘钥你来生成授权给你的下游就是了,后台再做记录ip的的功能,这样谁请求你的API了就都知道了,自己实现也很快的######tokening,或者id这些加密,获取后再解密,密钥自己生成。就是加个验证的key值就可以吧,每次提交数据验证key的正确性###### 做一个认证服务,提供一个认证的webapi,用户先访问它获取token,然后拿着token去访问所有的webapi。每次接收到请求就拿着token找认证服务寻求验证。验证通过则papapa,不然就404。 你要说的是这种么?还是对访问做验证限制? ######回复 @devilsitan : 也是啊,那你再看看刚刚问的第二个问题###### @liujiduo tomcat只是个web服务器。。不明白为什么和它要有关呢。。webapi又不是在tomcat上跑的。######回复 @devilsitan : 还有就是这种给webapi加token认证的方式,应该是我事先给某些指定的APP(比如我的iOS客户端或安卓客户端)发放私钥,然后它们根据私钥获取token。那如果我的网站前端通过ajax访问这些api是不是也需要通过token认证呢?如果是的话那不就会暴露出私钥了吗?先谢谢啦^_^######回复 @devilsitan : 那另一种 基于HTTP Digest认证的方式也是只用代码实现,不需要修改tomcat的配置吗?###### @liujiduo 那这种和服务器就没多大关系了啥。。只要你有webapi服务在就行,什么访问都是通过HTTP来请求的。接口也很简单一个认证,一个验证。认证服务内部看你怎么设计,要么是简单的用户-权限,要么是用户-角色-权限,要么是带约束的用户-角色-权限,还有更加灵活的二者皆有,采取优先拒绝。###### 引用来自“devilsitan”的评论 做一个认证服务,提供一个认证的webapi,用户先访问它获取token,然后拿着token去访问所有的webapi。每次接收到请求就拿着token找认证服务寻求验证。验证通过则papapa,不然就404。 你要说的是这种么?还是对访问做验证限制? 肯定是要带Token的,访问还是用户名密码,认证通过cookie里存的就是用户名和token,token是有有效期的,过了有效期你就需要重新分配一个token。这个暴露问题,我也不知道肿么办,不过人家要存心搞你,这些还有用么。你看Digest还不是私钥放在cookie里,虽然用算法加密一次和服务器比对,人家只需要截下你的包,把加密后的验证字符拿去验证就是了。我没看出什么区别######回复 @liujiduo : 可以参考上面的那位给的亚马逊s3的rest api认证。也可以看下openstack的keystone的验证模式。都是一个令牌,就看你怎么用和。简单的就是我前面说的那样,复杂的更安全的就是他们那样。######明白了,谢谢!###### 顶 ######ajax的时候检测客户端用户权限不可以吗?###### Http Digest认证也就是防止重放攻击,如果是局域网项目感觉对认证的要求不用太高,主要还是网络安全和访问的监控和预警,要是互联网的觉得还是非对称签名比较安全,存粹算法决定。###### 引用来自“HandMU”的评论ajax的时候检测客户端用户权限不可以吗? 用户权限是跟用户绑定的,而客户端访问接口可能没有用户的概念,这样就不合适了啊######回复 @HandMU : 你没明白他意思,webapi,可能是非本系统用户######可参考open auth######回复 @liujiduo : 都会有基于用户权限检测的。你钻到死角了。######回复 @HandMU : 是啊,难道对于webapi的安全认证就没有一个好的办法么?不知道淘宝这些网站是怎么做的######ajax理论上还是post、get,依然带上所有你能使用的用户信息。###### 引用来自“刘敬伟”的评论 Http Digest认证也就是防止重放攻击,如果是局域网项目感觉对认证的要求不用太高,主要还是网络安全和访问的监控和预警,要是互联网的觉得还是非对称签名比较安全,存粹算法决定。 不是局域网项目,我是想让某些数据敏感的接口只能被已授权的客户端访问,而不是让别人只要知道了url就能恶意请求和操纵我的接口,我查了Http Basic和Http Digest的认证流程,但就是不清楚怎么应用到项目中来。######我觉得你的思路有点混乱,没搞清楚到底认证什么,怎么认证,认证力度如何。这些都要根据你的网络环境、服务器系统、还有你处理的数据类型有关系。如果不想用第三方安全策略,我建议采用非对称的安全算法,针对用户信息最签名和验证。在这个基础上对你接口接收的用户请求进行监控,如果有必要的话你接收的数据要进行过滤,就像支付宝也不是实时到账,中间肯定有一个审核数据的再次分发的缓冲处理机制。"

montos 2020-06-03 22:34:05 0 浏览量 回答数 0

回答

就ISO C标准(语言的正式定义)而言,访问其边界之外的数组具有“ 未定义的行为 ”。其字面意思是: 在使用非便携式或错误程序构造或错误数据时的行为,对此国际标准不施加任何要求 一个非规范性的注释扩展了这一点: 可能的不确定行为范围从完全忽略具有无法预测结果的情况到在翻译或程序执行过程中以环境特征记录的方式表现(带有或不带有诊断消息)到终止翻译或执行(带有发布)诊断消息)。 这就是理论。现实是什么? 在“最佳”情况下,您将访问一些内存,这些内存要么是当前正在运行的程序所拥有的(这可能导致您的程序行为不当),要么不是当前正在运行的程序所拥有的(这可能会导致您的程序崩溃,例如细分错误)。或者,您可以尝试写入程序拥有的内存,但是将其标记为只读;这也可能导致程序崩溃。 假设您的程序在一个试图保护彼此并发运行的进程彼此之间的操作系统下运行。如果您的代码在“裸机”上运行,比如说它是OS内核或嵌入式系统的一部分,则没有这种保护;您行为不当的代码就是应该提供这种保护的内容。在这种情况下,损坏的可能性会更大,包括在某些情况下对硬件(或附近的东西或人)的物理损坏。 即使在受保护的OS环境中,保护也不总是100%。例如,存在一些操作系统错误,这些错误使无特权的程序可以获取根(管理)访问权限。即使具有普通用户特权,出现故障的程序也可能消耗过多的资源(CPU,内存,磁盘),从而可能使整个系统瘫痪。许多恶意软件(病毒等)利用缓冲区溢出来获得对系统的未授权访问。 (一个历史示例:我听说过,在一些带有核心内存的旧系统中,在紧密循环中重复访问单个内存位置可能确实导致该内存块融化。其他可能性包括破坏CRT显示器和移动读取的内容。 /写入磁盘驱动器磁头,使其具有驱动器柜的谐波频率,从而使其滑过桌子并掉落在地板上。) 而且总是有天网需要担心。 底线是:如果您可以编写一个程序来故意做一些不好的事情,那么从理论上讲,一个有缺陷的程序至少有可能偶然地做同样的事情。 在实践中,这是非常不可能的,你与MacOS X系统上运行错误的程序会做什么比暴跌更加严重。但是,不可能完全防止错误的代码做真正的坏事。 问题来源于stack overflow

保持可爱mmm 2020-01-16 15:55:44 0 浏览量 回答数 0

回答

break; 11 case "0002,0013"://文件生成程序的标题 12 return "SH"; 13 break; 14 case "0008,0005"://文本编码 15 return "CS"; 16 break; 17 case "0008,0008": 18 return "CS"; 19 break; 20 case "0008,1032"://成像时间 21 return "SQ"; 22 break; 23 case "0008,1111": 24 return "SQ"; 25 break; 26 case "0008,0020"://检查日期 27 return "DA"; 28 break; 29 case "0008,0060"://成像仪器 30 return "CS"; 31 break; 32 case "0008,0070"://成像仪厂商 33 return "LO"; 34 break; 35 case "0008,0080": 36 return "LO"; 37 break; 38 case "0010,0010"://病人姓名 39 return "PN"; 40 break; 41 case "0010,0020"://病人id 42 return "LO"; 43 break; 44 case "0010,0030"://病人生日 45 return "DA"; 46 break; 47 case "0018,0060"://电压 48 return "DS"; 49 break; 50 case "0018,1030"://协议名 51 return "LO"; 52 break; 53 case "0018,1151": 54 return "IS"; 55 break; 56 case "0020,0010"://检查ID 57 return "SH"; 58 break; 59 case "0020,0011"://序列 60 return "IS"; 61 break; 62 case "0020,0012"://成像编号 63 return "IS"; 64 break; 65 case "0020,0013"://影像编号 66 return "IS"; 67 break; 68 case "0028,0002"://像素采样1为灰度3为彩色 69 return "US"; 70 break; 71 case "0028,0004"://图像模式MONOCHROME2为灰度 72 return "CS"; 73 break; 74 case "0028,0010"://row高 75 return "US"; 76 break; 77 case "0028,0011"://col宽 78 return "US"; 79 break; 80 case "0028,0100"://单个采样数据长度 81 return "US"; 82 break; 83 case "0028,0101"://实际长度 84 return "US"; 85 break; 86 case "0028,0102"://采样最大值 87 return "US"; 88 break; 89 case "0028,1050"://窗位 90 return "DS"; 91 break; 92 case "0028,1051"://窗宽 93 return "DS"; 94 break; 95 case "0028,1052": 96 return "DS"; 97 break; 98 case "0028,1053": 99 return "DS"; 100 break; 101 case "0040,0008"://文件夹标签 102 return "SQ"; 103 break; 104 case "0040,0260"://文件夹标签 105 return "SQ"; 106 break; 107 case "0040,0275"://文件夹标签 108 return "SQ"; 109 break; 110 case "7fe0,0010"://像素数据开始处 111 return "OW"; 112 break; 113 default: 114 return "UN"; 115 break; 116 } 117 } 复制代码 最关键的两个tag: 0002,0010 普通tag的读取方式 little字节序还是big字节序 隐式VR还是显示VR。由它的值决定 复制代码 1 switch (VFStr) 2 { 3 case "1.2.840.10008.1.2.10"://显示little 4 isLitteEndian = true; 5 isExplicitVR = true; 6 break; 7 case "1.2.840.10008.1.2.20"://显示big 8 isLitteEndian = false; 9 isExplicitVR = true; 10 break; 11 case "1.2.840.10008.1.20"://隐式little 12 isLitteEndian = true; 13 isExplicitVR = false; 14 break; 15 default: 16 break; 17 } 复制代码 7fe0,0010 像素数据开始处 整理 根据以上的分析相信解析一个dicom格式文件的过程已经很清晰了吧 第一步:跳过128字节导言部分,并读取"DICM"4个字符 以确认是dicom格式文件 第二步:读取第一部分 也就是非常重要的文件元dataElement 。读取所有0002开头的tag 并根据0002,0010的值确定传输语法。文件元tag部分的数据元素都是以显示VR的方式表示的 读取它的值 也就是字节码处理 别告诉我说你不会字节码处理哈。传输语法 说得那么官方,你就忽悠吧 其实就确定两个东西而已 1字节序 这个基本上都是little字节序。举个例子吧十进制数 35280 用十六进制表示是0xff00 但是存储到文件中你用十六进制编辑器打开你看到的是这个样子00ff 这就是little字节序。平常我们用的x86PC在windows下都是little字节序 包括AMD的CPU。别太较真 较真的话这个问题又可以写篇博客了。 2确定从0002以后的dataElement的VR是显示还是隐式。说来说去0002,0010的值就 那么固定几个 并且只能是那么几个 这些都在那个北美放射学会定义的dicom标准的第六章 有说明 : 1.2.840.10008.1.2 Implicit VR Little Endian: Default Transfer Syntax for DICOM Transfer Syntax 1.2.840.10008.1.2.1 Explicit VR Little Endian Transfer Syntax 1.2.840.10008.1.2.2 Explicit VR Big Endian Transfer Syntax 上面的那段代码其实就是这个表格的实现,讲到这里你会觉得多么的坑爹啊 是的dicom面向对象的破概念非常烦的。 第三步:读取普通tag 直到搜寻到7fe0,0010 这个最巨体的存储图像数据的 dataElement 它一个顶别人几十个 上百个。我们在前一步已经把VR是显示还是隐式确定 通过前面的图 ,也就是字节码处理而已无任何压力。显示情况下根据VR 和Len 确定数据类型 跟数据长度直接读取就可以了。隐式情况下这破玩艺儿有点烦,只能根据tag 字典确定它是什么VR再才能读取。关于这个字典也在dicom标准的第六章。上面倒数第二段代码已经把重要的字典都列了出来。 第四步:读取灰度像素数据并调窗 以GDI的方式显示出来。 说实话开始我还以为dicom这种号称医学什么影像的专家制定出来的标准 读取像素数据应该有难度吧 结果没想到这么的傻瓜。直接按像素从左到右从上到下 一行行依次扫描。两个字节表示1个像素普通Dicom格式存储的是16位的灰度图像,其实有效数据只有12位,除去0 所以最高值是2047。比如CT值 从-1000到+1000,空气的密度为-1000 水的密度为0 金属的密度为+1000 总共的值为2000 调窗技术: 即把12级灰度的数据 通过调节窗宽窗位并让他在RGB模式下显示出来。还技术呢 说实话这个也是没什么技术含量的所谓的技术,两句代码给你整明白。 调节窗宽窗位到底什么意思,12位的数据那么它总共有2047个等级的灰度 没有显示设备可以体现两千多级的明暗度 就算有我们肉眼也无法分辨更无法诊断。我们要诊断是要提取关键密度值的数据 在医院放射科呆久了你一定经常听医生讲什么骨窗 肺窗 之类的词儿,这就是指的这个“窗”。比如有病人骨折了打了钢板我们想看金属部分来诊断 那么我们应该抓取CT值从800到1000 密度的像素 也就是灰度值 然后把它放到RGB模式下显示,低于800的不论值大小都显示黑色 高于1000的不论值大小都显示白色。 通过以上例子那么这个范围1000-800=200 这个200表示窗宽,800+(200/2)这个表示窗位 一句话,从2047个等级的灰度里选取一个范围放到0~255的灰度环境里显示。 怎样把12位灰度影射到8位灰度显示出来呢,还怎么显示 上面方法都给说明了基本上算半成品了。联想到角度制弧度制,设要求的8位灰度值为x 已知的12位灰度值为y那么:x/255=y/2047 那么x=255y/2047 原理不多讲 等比中项十字相乘法 这个是初中的知识哈。初中没读过的童鞋飘过。。。 原理过程讲完了 代码走起 复制代码 1 class DicomHandler 2 { 3 string fileName = ""; 4 Dictionary tags = new Dictionary();//dicom文件中的标签 5 BinaryReader dicomFile;//dicom文件流 6 7 //文件元信息 8 public Bitmap gdiImg;//转换后的gdi图像 9 UInt32 fileHeadLen;//文件头长度 10 long fileHeadOffset;//文件数据开始位置 11 UInt32 pixDatalen;//像素数据长度 12 long pixDataOffset = 0;//像素数据开始位置 13 bool isLitteEndian = true;//是否小字节序(小端在前 、大端在前) 14 bool isExplicitVR = true;//有无VR 15 16 //像素信息 17 int colors;//颜色数 RGB为3 黑白为1 18 public int windowWith = 2048, windowCenter = 2048 / 2;//窗宽窗位 19 int rows, cols; 20 public void readAndShow(TextBox textBox1) 21 { 22 if (fileName == string.Empty) 23 return; 24 dicomFile = new BinaryReader(File.OpenRead(fileName)); 25 26 //跳过128字节导言部分 27 dicomFile.BaseStream.Seek(128, SeekOrigin.Begin); 28 29 if (new string(dicomFile.ReadChars(4)) != "DICM") 30 { 31 MessageBox.Show("没有dicom标识头,文件格式错误"); 32 return; 33 } 34 35 36 tagRead(); 37 38 IDictionaryEnumerator enor = tags.GetEnumerator(); 39 while (enor.MoveNext()) 40 { 41 if (enor.Key.ToString().Length > 9) 42 { 43 textBox1.Text += enor.Key.ToString() + "rn"; 44 textBox1.Text += enor.Value.ToString().Replace('0', ' '); 45 } 46 else 47 textBox1.Text += enor.Key.ToString() + enor.Value.ToString().Replace('0', ' ') + "rn"; 48 } 49 dicomFile.Close(); 50 } 51 public DicomHandler(string _filename) 52 { 53 fileName = _filename; 54 } 55 56 public void saveAs(string filename) 57 { 58 switch (filename.Substring(filename.LastIndexOf('.'))) 59 { 60 case ".jpg": 61 gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg); 62 break; 63 case ".bmp": 64 gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp); 65 break; 66 case ".png": 67 gdiImg.Save(filename, System.Drawing.Imaging.ImageFormat.Png); 68 break; 69 default: 70 break; 71 } 72 } 73 public bool getImg( )//获取图像 在图像数据偏移量已经确定的情况下 74 { 75 if (fileName == string.Empty) 76 return false; 77 78 int dataLen, validLen;//数据长度 有效位 79 int imgNum;//帧数 80 81 rows = int.Parse(tags["0028,0010"].Substring(5)); 82 cols = int.Parse(tags["0028,0011"].Substring(5)); 83 84 colors = int.Parse(tags["0028,0002"].Substring(5)); 85 dataLen = int.Parse(tags["0028,0100"].Substring(5)); 86 validLen = int.Parse(tags["0028,0101"].Substring(5)); 87 88 gdiImg = new Bitmap(cols, rows); 89 90 BinaryReader dicomFile = new BinaryReader(File.OpenRead(fileName)); 91 92 dicomFile.BaseStream.Seek(pixDataOffset, SeekOrigin.Begin); 93 94 long reads = 0; 95 for (int i = 0; i < gdiImg.Height; i++) 96 { 97 for (int j = 0; j < gdiImg.Width; j++) 98 { 99 if (reads >= pixDatalen) 100 break; 101 byte[] pixData = dicomFile.ReadBytes(dataLen / 8 * colors); 102 reads += pixData.Length; 103 104 Color c = Color.Empty; 105 if (colors == 1) 106 { 107 int grayGDI; 108 109 double gray = BitConverter.ToUInt16(pixData, 0); 110 //调窗代码,就这么几句而已 111 //1先确定窗口范围 2映射到8位灰度 112 int grayStart = (windowCenter - windowWith / 2); 113 int grayEnd = (windowCenter + windowWith / 2); 114 115 if (gray < grayStart) 116 grayGDI = 0; 117 else if (gray > grayEnd) 118 grayGDI = 255; 119 else 120 { 121 grayGDI = (int)((gray - grayStart) * 255 / windowWith); 122 } 123 124 if (grayGDI > 255) 125 grayGDI = 255; 126 else if (grayGDI < 0) 127 grayGDI = 0; 128 c = Color.FromArgb(grayGDI, grayGDI, grayGDI); 129 } 130 else if (colors == 3) 131 { 132 c = Color.FromArgb(pixData[0], pixData[1], pixData[2]); 133 } 134 135 gdiImg.SetPixel(j, i, c); 136 } 137 } 138 139 dicomFile.Close(); 140 return true; 141 } 142 void tagRead()//不断读取所有tag 及其值 直到碰到图像数据 (7fe0 0010 ) 143 { 144 bool enDir = false; 145 int leve = 0; 146 StringBuilder folderData = new StringBuilder();//该死的文件夹标签 147 string folderTag = ""; 148 while (dicomFile.BaseStream.Position + 6 < dicomFile.BaseStream.Length) 149 { 150 //读取tag 151 string tag = dicomFile.ReadUInt16().ToString("x4") + "," + 152 dicomFile.ReadUInt16().ToString("x4"); 153 154 string VR = string.Empty; 155 UInt32 Len = 0; 156 //读取VR跟Len 157 //对OB OW SQ 要做特殊处理 先置两个字节0 然后4字节值长度 158 //------------------------------------------------------这些都是在读取VR一步被阻断的情况 159 if (tag.Substring(0, 4) == "0002")//文件头 特殊情况 160 { 161 VR = new string(dicomFile.ReadChars(2)); 162 163 if (VR == "OB" || VR == "OW" || VR == "SQ" || VR == "OF" || VR == "UT" || VR == "UN") 164 { 165 dicomFile.BaseStream.Seek(2, SeekOrigin.Current); 166 Len = dicomFile.ReadUInt32(); 167 } 168 else 169 Len = dicomFile.ReadUInt16(); 170 } 171 else if (tag == "fffe,e000" || tag == "fffe,e00d" || tag == "fffe,e0dd")//文件夹标签 172 { 173 VR = "**"; 174 Len = dicomFile.ReadUInt32(); 175 } 176 else if (isExplicitVR == true)//有无VR的情况 177 { 178 VR = new string(dicomFile.ReadChars(2)); 179 180 if (VR == "OB" || VR == "OW" || VR == "SQ" || VR == "OF" || VR == "UT" || VR == "UN") 181 { 182 dicomFile.BaseStream.Seek(2, SeekOrigin.Current); 183 Len = dicomFile.ReadUInt32(); 184 } 185 else 186 Len = dicomFile.ReadUInt16(); 187 } 188 else if (isExplicitVR == false) 189 { 190 VR = getVR(tag);//无显示VR时根据tag一个一个去找 真烦啊。 191 Len = dicomFile.ReadUInt32(); 192 } 193 //判断是否应该读取VF 以何种方式读取VF 194 //-------------------------------------------------------这些都是在读取VF一步被阻断的情况 195 byte[] VF = { 0x00 }; 196 197 if (tag == "7fe0,0010")//图像数据开始了 198 { 199 pixDatalen = Len; 200 pixDataOffset = dicomFile.BaseStream.Position; 201 dicomFile.BaseStream.Seek(Len, SeekOrigin.Current); 202 VR = "UL"; 203 VF = BitConverter.GetBytes(Len); 204 } 205 else if ((VR == "SQ" && Len == UInt32.MaxValue) || (tag == "fffe,e000" && Len == UInt32.MaxValue))//靠 遇到文件夹开始标签了 206 { 207 if (enDir == false) 208 { 209 enDir = true; 210 folderData.Remove(0, folderData.Length); 211 folderTag = tag; 212 } 213 else 214 { 215 leve++;//VF不赋值 216 } 217 } 218 else if ((tag == "fffe,e00d" && Len == UInt32.MinValue) || (tag == "fffe,e0dd" && Len == UInt32.MinValue))//文件夹结束标签 219 { 220 if (enDir == true) 221 { 222 enDir = false; 223 } 224 else 225 { 226 leve--; 227 } 228 } 229 else 230 VF = dicomFile.ReadBytes((int)Len); 231 232 string VFStr; 233 234 VFStr = getVF(VR, VF); 235 236 //----------------------------------------------------------------针对特殊的tag的值的处理 237 //特别针对文件头信息处理 238 if (tag == "0002,0000") 239 { 240 fileHeadLen = Len; 241 fileHeadOffset = dicomFile.BaseStream.Position; 242 } 243 else if (tag == "0002,0010")//传输语法 关系到后面的数据读取 244 { 245 switch (VFStr) 246 { 247 case "1.2.840.10008.1.2.10"://显示little 248 isLitteEndian = true; 249 isExplicitVR = true; 250 break; 251 case "1.2.840.10008.1.2.20"://显示big 252 isLitteEndian = false; 253 isExplicitVR = true; 254 break; 255 case "1.2.840.10008.1.20"://隐式little 256 isLitteEndian = true; 257 isExplicitVR = false; 258 break; 259 default: 260 break; 261 } 262 } 263 for (int i = 1; i <= leve; i++) 264 tag = "--" + tag; 265 //------------------------------------数据搜集代码 266 if ((VR == "SQ" && Len == UInt32.MaxValue) || (tag == "fffe,e000" && Len == UInt32.MaxValue) || leve > 0)//文件夹标签代码 267 { 268 folderData.AppendLine(tag + "(" + VR + "):" + VFStr); 269 } 270 else if (((tag == "fffe,e00d" && Len == UInt32.MinValue) || (tag == "fffe,e0dd" && Len == UInt32.MinValue)) && leve == 0)//文件夹结束标签 271 { 272 folderData.AppendLine(tag + "(" + VR + "):" + VFStr); 273 tags.Add(folderTag + "SQ", folderData.ToString()); 274 } 275 else 276 tags.Add(tag, "(" + VR + "):" + VFStr); 277 } 278 } 279 } 复制代码 好了收工。 测试下成果 复制代码 1 if (openFileDialog1.ShowDialog() != DialogResult.OK) 2 return; 3 4 string fileName = openFileDialog1.FileName; 5 6 handler = new DicomHandler(fileName); 7 8 handler.readAndShow(textBox1); 9 10 this.Text = "DicomViewer-" + openFileDialog1.FileName; 11 12 13 backgroundWorker1.RunWorkerAsync(); 复制代码 这里处理gdi位图的时候直接用的setPix 处理速度比较慢所以用了backgroundWorker,实际应用中请使用内存缓冲跟指针的方式 否则效率低了是得不到客户的认可的哦,gdi位图操作可使用lockBits加指针的方式 ,12位的灰度像素数据可以第一次读取后缓存到内存中 以方便后面调窗的快速读取 优化这点代码也不难哈 对指针什么的熟点就行了,前几章都有。 这是ezDicom 经过公认测试的软件 我们来跟他对比一下,打开 调窗测试,我们注意到两个东西 在没有窗宽窗位时 默认窗宽是2047+1即2048 窗位是2048/2即1024 直观的感受是调窗宽像在调图像对比度 ,调窗位像在调图像亮度。 窗宽为255的时候图像是最瑞丽的 因为255其实就是8位图像的默认窗宽。 注意窗位那里有小小区别,ez窗位显示的是根据1024那里为0开始偏移 而我的程序是根据窗宽中间值没有偏移 没有偏移的情况稍微符合逻辑点吧。 但是可以看到原理是一样的 结果是一样的。

爵霸 2019-12-02 02:13:35 0 浏览量 回答数 0

回答

关于swap交换分区的设置:一种流行的、以讹传讹的说法是,安装Linux系统时,交换分区swap的大小应该是内存的两倍。也就是说,如果内存是2G,那么就应该分出4G的硬盘空间作为交换空间。其实这是严重的浪费。真实的情况是:可以根据你系统内存的大小,以及所使用的程序,自行决定交换分区的大小,甚至可以完全不用交换分区!首先解释一下什么是交换分区。交换分区,英文的说法是swap,意思是“交换”、“实物交易”。它的功能就是在内存不够的情况下,操作系统先把内存中暂时不用的数据,存到硬盘的交换空间,腾出内存来让别的程序运行,和Windows的虚拟内存(pagefile.sys)的作用是一样的。做一个假设:如果你的内存足够大,极少出现内存不足的情况,那么你就不需要交换分区。事实上,这种可能性是完全存在的。现在的1G内存的电脑不算什么了。动辄4G内存的电脑也日益普遍。日常使用的话,很少能用完全部的内存。在用不完内存容量的情况下,还要划出它两倍的硬盘空间用于内存交换,这不是浪费吗?可以说,在你内存基本够用的情况下,完全可以不要交换空间。在Windows下也是一样,在系统属性中,把虚拟内存设置为0,系统依然运行的很好。当然,如果你用的是服务器,还是要有专门的虚拟内存,有备无患。但是虚拟内存的大小不一定非要内存的两倍。那么怎么知道你的系统有没有用到交换空间呢?只需要在root用户下,运行下面的命令就可以知道了。free -m在日常应用中,通过上述命令看到交换空间的使用情况为0,那么你就不需要很大的虚拟内存,甚至可以完全不需要另辟硬盘空间作为虚拟内存。那么,万一有一天你需要了呢,难道要重装系统?大可不必,在Linux下虚拟内存不单可以放在单独的交换分区,也可以是一个在正常分区下的交换文件。1 查看swap 空间大小(总计): # free -m 默认单位为k, -m 单位为M   total used free shared buffers cached   Mem: 377 180 197 0 19 110   -/+ buffers/cache: 50 327   Swap: 572 0 5722 查看swap 空间(file(s)/partition(s)): 包括 文件 和 分区 的详细信息  # swapon -s  等价于  # cat /proc/swaps3 添加交换空间  两种选择:添加一个交换分区或添加一个交换文件。推荐你添加一个交换分区;不过,若你没有多少空闲空间可用,则添加交换文件。3.1 添加一个交换分区  步骤如下: a 使用fdisk来创建交换分区(假设 /dev/sdb2 是创建的交换分区) b 使用 mkswap 命令来设置交换分区:   # mkswap /dev/sdb2 c 启用交换分区:   # swapon /dev/sdb2 d 写入/etc/fstab,以便在引导时启用:   /dev/sdb2 swap swap defaults 0 03.2 添加一个交换文件  a 创建大小为512M的交换文件:   # dd if=/dev/zero of=/swapfile1 bs=1024k count=512  b 使用 mkswap 命令来设置交换文件:   # mkswap /swapfile1  c 启用交换分区:   # swapon /swapfile1  d 写入/etc/fstab,以便在引导时启用:   /swapfile1 swap swap defaults 0 0  新添了交换分区并启用它之后,请查看cat /proc/swaps 或 free 命令的输出来确保交换分区已被启用了。4 删除交换空间:  a 禁用交换分区:   # swapoff /dev/sdb2  b 从 /etc/fstab 中删除项目;  c 使用fdisk或yast工具删除分区。  删除交换文件步骤同上。--------------------------------------------------------------------------------   # free -m    total used free shared buffers cached   Mem: 377 180 197 0 19 110   -/+ buffers/cache: 50 327   Swap: 572 0 572Mem 行显示了从系统角度看来内存使用的情况, total是系统可用的内存大小, 数量上等于系统物理内存减去内核保留的内存.buffers和cached是系统用做缓冲的内存. buffers与某个块设备关联, 包含了文件系统元数据, 并且跟踪了块的变化. cache只包含了文件本身.-/+ buffers/cache 行则从用户角度显示内存信息, 可用内存从数量上等于mem行used列值减去buffers和cached内存的大小.因为buffers和cached是操作系统为加快系统运行而设置的, 当用户需要时, 可以只接为用户使用.top 显示系统运行时的各进程动态、实时的状态(cpu、内存)top 中有3个列 VIRT RES SHR, 标示了进程使用的内存情况.VIRT 标识这个进程可以使用的内存总大小, 包括这个进程真实使用的内存, 映射过的文件, 和别的进程共享的内存等.RES 标识这个这个进程真实占用内存的大小.SHR 标识可以和别的进程共享的内存和库大小.vmstat 显示内存的使用情况这些命令都是从/proc/meminfo中读取内存信息.关于/proc/meminfo中各行的含意, 在内核源代码的Documentation/filesystems/proc.txt文件中有叙述系统的真实内存大小可以用 dmesg | grep mM[mM]看到/proc/pid/status显示一个进程的详细状态# cat /proc/5346/status Name: bash State: S (sleeping) SleepAVG: 98% Tgid: 5346 Pid: 5346 PPid: 5343 TracerPid: 0 Uid: 1000 1000 1000 1000 Gid: 104 104 104 104 FDSize: 256 Groups: 6 24 29 44 104 113 1000 1001 VmPeak: 6528 kB VmSize: 6528 kB VmLck: 0 kB VmHWM: 1976 kB VmRSS: 1976 kB VmData: 752 kB VmStk: 84 kB VmExe: 644 kB VmLib: 1788 kB VmPTE: 16 kB Threads: 1 SigQ: 0/4294967295 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000384004 SigCgt: 000000004b813efb CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000VmSize即为该进程内存总大小, 和top输出中的VIRT一致.

云栖技术 2019-12-02 02:35:43 0 浏览量 回答数 0

回答

Nginx是一个轻量级的,高性能的Web服务器以及反向代理和邮箱 (IMAP/POP3)代理服务器。它运行在UNIX,GNU /linux,BSD 各种版本,Mac OS X,Solaris和Windows。根据调查统计,6%的网站使用Nginx Web服务器。Nginx是少数能处理C10K问题的服务器之一。跟传统的服务器不同,Nginx不依赖线程来处理请求。相反,它使用了更多的可扩展的事 件驱动(异步)架构。Nginx为一些高流量的网站提供动力,比如WordPress,人人网,腾讯,网易等。这篇文章主要是介绍如何提高运行在 Linux或UNIX系统的Nginx Web服务器的安全性。 默认配置文件和Nginx端口 /usr/local/nginx/conf/ – Nginx配置文件目录,/usr/local/nginx/conf/nginx.conf是主配置文件 /usr/local/nginx/html/ – 默认网站文件位置 /usr/local/nginx/logs/ – 默认日志文件位置 Nginx HTTP默认端口 : TCP 80 Nginx HTTPS默认端口: TCP 443 你可以使用以下命令来测试Nginx配置文件准确性。 /usr/local/nginx/sbin/nginx -t 将会输出: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok configuration file /usr/local/nginx/conf/nginx.conf test is successful 执行以下命令来重新加载配置文件。 /usr/local/nginx/sbin/nginx -s reload 执行以下命令来停止服务器。 /usr/local/nginx/sbin/nginx -s stop 一、配置SELinux 注意:对于云服务器 ECS,参阅 ECS 使用须知 ,基于兼容性、稳定性考虑,请勿开启 SELinux。 安全增强型 Linux(SELinux)是一个Linux内核的功能,它提供支持访问控制的安全政策保护机制。它可以防御大部分攻击。下面我们来看如何启动基于centos/RHEL系统的SELinux。 安装SELinux rpm -qa | grep selinux libselinux-1.23.10-2 selinux-policy-targeted-1.23.16-6 如果没有返回任何结果,代表没有安装 SELinux,如果返回了类似上面的结果,则说明系统安装了 SELinux。 布什值锁定 运行命令getsebool -a来锁定系统。 getsebool -a | less getsebool -a | grep off getsebool -a | grep o 二、通过分区挂载允许最少特权 服务器上的网页/html/php文件单独分区。例如,新建一个分区/dev/sda5(第一逻辑分区),并且挂载在/nginx。确保 /nginx是以noexec, nodev and nosetuid的权限挂载。以下是我的/etc/fstab的挂载/nginx的信息: LABEL=/nginx /nginx ext3 defaults,nosuid,noexec,nodev 1 2 注意:你需要使用fdisk和mkfs.ext3命令创建一个新分区。 三、配置/etc/sysctl.conf强化Linux安全 你可以通过编辑/etc/sysctl.conf来控制和配置Linux内核、网络设置。 Avoid a smurf attack net.ipv4.icmp_echo_ignore_broadcasts = 1 Turn on protection for bad icmp error messages net.ipv4.icmp_ignore_bogus_error_responses = 1 Turn on syncookies for SYN flood attack protection net.ipv4.tcp_syncookies = 1 Turn on and log spoofed, source routed, and redirect packets net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 No source routed packets here net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 Turn on reverse path filtering net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 Make sure no one can alter the routing tables net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 Don’t act as a router net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 Turn on execshild kernel.exec-shield = 1 kernel.randomize_va_space = 1 Tuen IPv6 net.ipv6.conf.default.router_solicitations = 0 net.ipv6.conf.default.accept_ra_rtr_pref = 0 net.ipv6.conf.default.accept_ra_pinfo = 0 net.ipv6.conf.default.accept_ra_defrtr = 0 net.ipv6.conf.default.autoconf = 0 net.ipv6.conf.default.dad_transmits = 0 net.ipv6.conf.default.max_addresses = 1 Optimization for port usefor LBs Increase system file descriptor limit fs.file-max = 65535 Allow for more PIDs (to reduce rollover problems); may break some programs 32768 kernel.pid_max = 65536 Increase system IP port limits net.ipv4.ip_local_port_range = 2000 65000 Increase TCP max buffer size setable using setsockopt() net.ipv4.tcp_rmem = 4096 87380 8388608 net.ipv4.tcp_wmem = 4096 87380 8388608 Increase Linux auto tuning TCP buffer limits min, default, and max number of bytes to use set max to at least 4MB, or higher if you use very high BDP paths Tcp Windows etc net.core.rmem_max = 8388608 net.core.wmem_max = 8388608 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_window_scaling = 1 四、删除所有不需要的Nginx模块 你需要直接通过编译Nginx源代码使模块数量最少化。通过限制只允许web服务器访问模块把风险降到最低。你可以只配置安装nginx你所需要的模块。例如,禁用SSL和autoindex模块你可以执行以下命令: ./configure –without-http_autoindex_module –without-http_ssi_module make make install 通过以下命令来查看当编译nginx服务器时哪个模块能开户或关闭: ./configure –help | less 禁用你用不到的nginx模块。 (可选项)更改nginx版本名称。 编辑文件/http/ngx_http_header_filter_module.c: vi +48 src/http/ngx_http_header_filter_module.c 找到行: static char ngx_http_server_string[] = “Server: nginx” CRLF; static char ngx_http_server_full_string[] = “Server: ” NGINX_VER CRLF; 按照以下行修改: static char ngx_http_server_string[] = “Server: Ninja Web Server” CRLF; static char ngx_http_server_full_string[] = “Server: Ninja Web Server” CRLF; 保存并关闭文件。现在你可以编辑服务器了。增加以下代码到nginx.conf文件来关闭nginx版本号的显示。 server_tokens off 五、使用mod_security(只适合后端Apache服务器) mod_security为Apache提供一个应用程序级的防火墙。为后端Apache Web服务器安装mod_security,这会阻止很多注入式攻击。 六、安装SELinux策略以强化Nginx Web服务器 默认的SELinux不会保护Nginx Web服务器,但是你可以安装和编译保护软件。 1、安装编译SELinux所需环境支持 yum -y install selinux-policy-targeted selinux-policy-devel 2、下载SELinux策略以强化Nginx Web服务器。 cd /opt wget ‘http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc’ 3、解压文件 tar -zxvf se-ngix_1_0_10.tar.gz 4、编译文件 cd se-ngix_1_0_10/nginx make 将会输出如下: Compiling targeted nginx module /usr/bin/checkmodule: loading policy configuration from tmp/nginx.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 6) to tmp/nginx.mod Creating targeted nginx.pp policy package rm tmp/nginx.mod.fc tmp/nginx.mod 5、安装生成的nginx.pp SELinux模块: /usr/sbin/semodule -i nginx.pp 七、基于Iptables防火墙的限制 下面的防火墙脚本阻止任何除了允许: 来自HTTP(TCP端口80)的请求 来自ICMP ping的请求 ntp(端口123)的请求输出 smtp(TCP端口25)的请求输出 #!/bin/bash IPT=”/sbin/iptables” IPS Get server public ip SERVER_IP=$(ifconfig eth0 | grep ‘inet addr:’ | awk -F’inet addr:’ ‘{ print $2}’ | awk ‘{ print $1}’) LB1_IP=”204.54.1.1″ LB2_IP=”204.54.1.2″ Do some smart logic so that we can use damm script on LB2 too OTHER_LB=”" SERVER_IP=”" [[ "$SERVER_IP" == "$LB1_IP" ]] && OTHER_LB=”$LB2_IP” || OTHER_LB=”$LB1_IP” [[ "$OTHER_LB" == "$LB2_IP" ]] && OPP_LB=”$LB1_IP” || OPP_LB=”$LB2_IP” IPs PUB_SSH_ONLY=”122.xx.yy.zz/29″ FILES BLOCKED_IP_TDB=/root/.fw/blocked.ip.txt SPOOFIP=”127.0.0.0/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 169.254.0.0/16 0.0.0.0/8 240.0.0.0/4 255.255.255.255/32 168.254.0.0/16 224.0.0.0/4 240.0.0.0/5 248.0.0.0/5 192.0.2.0/24″ BADIPS=$( [[ -f ${BLOCKED_IP_TDB} ]] && egrep -v “^#|^$” ${BLOCKED_IP_TDB}) Interfaces PUB_IF=”eth0″ # public interface LO_IF=”lo” # loopback VPN_IF=”eth1″ # vpn / private net start firewall echo “Setting LB1 $(hostname) Firewall…” DROP and close everything $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP Unlimited lo access $IPT -A INPUT -i ${LO_IF} -j ACCEPT $IPT -A OUTPUT -o ${LO_IF} -j ACCEPT Unlimited vpn / pnet access $IPT -A INPUT -i ${VPN_IF} -j ACCEPT $IPT -A OUTPUT -o ${VPN_IF} -j ACCEPT Drop sync $IPT -A INPUT -i ${PUB_IF} -p tcp ! –syn -m state –state NEW -j DROP Drop Fragments $IPT -A INPUT -i ${PUB_IF} -f -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL ALL -j DROP Drop NULL packets $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL NONE -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” NULL Packets “ $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL NONE -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,RST SYN,RST -j DROP Drop XMAS $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,FIN SYN,FIN -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” XMAS Packets “ $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,FIN SYN,FIN -j DROP Drop FIN packet scans $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags FIN,ACK FIN -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” Fin Packets Scan “ $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags FIN,ACK FIN -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP Log and get rid of broadcast / multicast and invalid $IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type broadcast -j LOG –log-prefix ” Broadcast “ $IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type broadcast -j DROP $IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type multicast -j LOG –log-prefix ” Multicast “ $IPT -A INPUT -i ${PUB_IF} -m pkttype –pkt-type multicast -j DROP $IPT -A INPUT -i ${PUB_IF} -m state –state INVALID -j LOG –log-prefix ” Invalid “ $IPT -A INPUT -i ${PUB_IF} -m state –state INVALID -j DROP Log and block spoofed ips $IPT -N spooflist for ipblock in $SPOOFIP do $IPT -A spooflist -i ${PUB_IF} -s $ipblock -j LOG –log-prefix ” SPOOF List Block “ $IPT -A spooflist -i ${PUB_IF} -s $ipblock -j DROP done $IPT -I INPUT -j spooflist $IPT -I OUTPUT -j spooflist $IPT -I FORWARD -j spooflist Allow ssh only from selected public ips for ip in ${PUB_SSH_ONLY} do $IPT -A INPUT -i ${PUB_IF} -s ${ip} -p tcp -d ${SERVER_IP} –destination-port 22 -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -d ${ip} -p tcp -s ${SERVER_IP} –sport 22 -j ACCEPT done allow incoming ICMP ping pong stuff $IPT -A INPUT -i ${PUB_IF} -p icmp –icmp-type 8 -s 0/0 -m state –state NEW,ESTABLISHED,RELATED -m limit –limit 30/sec -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -p icmp –icmp-type 0 -d 0/0 -m state –state ESTABLISHED,RELATED -j ACCEPT allow incoming HTTP port 80 $IPT -A INPUT -i ${PUB_IF} -p tcp -s 0/0 –sport 1024:65535 –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -p tcp –sport 80 -d 0/0 –dport 1024:65535 -m state –state ESTABLISHED -j ACCEPT allow outgoing ntp $IPT -A OUTPUT -o ${PUB_IF} -p udp –dport 123 -m state –state NEW,ESTABLISHED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p udp –sport 123 -m state –state ESTABLISHED -j ACCEPT allow outgoing smtp $IPT -A OUTPUT -o ${PUB_IF} -p tcp –dport 25 -m state –state NEW,ESTABLISHED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p tcp –sport 25 -m state –state ESTABLISHED -j ACCEPT add your other rules here ####################### drop and log everything else $IPT -A INPUT -m limit –limit 5/m –limit-burst 7 -j LOG –log-prefix ” DEFAULT DROP “ $IPT -A INPUT -j DROP exit 0 八、控制缓冲区溢出攻击 编辑nginx.conf,为所有客户端设置缓冲区的大小限制。 vi /usr/local/nginx/conf/nginx.conf 编辑和设置所有客户端缓冲区的大小限制如下: Start: Size Limits & Buffer Overflows client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k; END: Size Limits & Buffer Overflows 解释: 1、client_body_buffer_size 1k-(默认8k或16k)这个指令可以指定连接请求实体的缓冲区大小。如果连接请求超过缓存区指定的值,那么这些请求实体的整体或部分将尝试写入一个临时文件。 2、client_header_buffer_size 1k-指令指定客户端请求头部的缓冲区大小。绝大多数情况下一个请求头不会大于1k,不过如果有来自于wap客户端的较大的cookie它可能会大于 1k,Nginx将分配给它一个更大的缓冲区,这个值可以在large_client_header_buffers里面设置。 3、client_max_body_size 1k-指令指定允许客户端连接的最大请求实体大小,它出现在请求头部的Content-Length字段。 如果请求大于指定的值,客户端将收到一个”Request Entity Too Large” (413)错误。记住,浏览器并不知道怎样显示这个错误。 4、large_client_header_buffers-指定客户端一些比较大的请求头使用的缓冲区数量和大小。请求字段不能大于一个缓冲区大小,如果客户端发送一个比较大的头,nginx将返回”Request URI too large” (414) 同样,请求的头部最长字段不能大于一个缓冲区,否则服务器将返回”Bad request” (400)。缓冲区只在需求时分开。默认一个缓冲区大小为操作系统中分页文件大小,通常是4k或8k,如果一个连接请求最终将状态转换为keep- alive,它所占用的缓冲区将被释放。 你还需要控制超时来提高服务器性能并与客户端断开连接。按照如下编辑: Start: Timeouts client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; End: Timeouts 1、client_body_timeout 10;-指令指定读取请求实体的超时时间。这里的超时是指一个请求实体没有进入读取步骤,如果连接超过这个时间而客户端没有任何响应,Nginx将返回一个”Request time out” (408)错误。 2、client_header_timeout 10;-指令指定读取客户端请求头标题的超时时间。这里的超时是指一个请求头没有进入读取步骤,如果连接超过这个时间而客户端没有任何响应,Nginx将返回一个”Request time out” (408)错误。 3、keepalive_timeout 5 5; – 参数的第一个值指定了客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接。参数的第二个值(可选)指定了应答头中Keep-Alive: timeout=time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,如果不指定这个参数,nginx不会在应 答头中发送Keep-Alive信息。(但这并不是指怎样将一个连接“Keep-Alive”)参数的这两个值可以不相同。 4、send_timeout 10; 指令指定了发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,如果超过这个时间客户端没有任何响应,nginx将关闭连接。 九、控制并发连接 你可以使用NginxHttpLimitZone模块来限制指定的会话或者一个IP地址的特殊情况下的并发连接。编辑nginx.conf: Directive describes the zone, in which the session states are stored i.e. store in slimits. 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session limit_zone slimits $binary_remote_addr 5m; Control maximum number of simultaneous connections for one session i.e. restricts the amount of connections from a single ip address limit_conn slimits 5; 上面表示限制每个远程IP地址的客户端同时打开连接不能超过5个。 十、只允许我们的域名的访问 如果机器人只是随机扫描服务器的所有域名,那拒绝这个请求。你必须允许配置的虚拟域或反向代理请求。你不必使用IP地址来拒绝。 Only requests to our Host are allowed i.e. nixcraft.in, images.nixcraft.in and www.nixcraft.in if ($host !~ ^(nixcraft.in|www.nixcraft.in|images.nixcraft.in)$ ) { return 444; } 十一、限制可用的请求方法 GET和POST是互联网上最常用的方法。 Web服务器的方法被定义在RFC 2616。如果Web服务器不要求启用所有可用的方法,它们应该被禁用。下面的指令将过滤只允许GET,HEAD和POST方法: Only allow these request methods if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } Do not accept DELETE, SEARCH and other methods 更多关于HTTP方法的介绍 GET方法是用来请求,如文件http://www.moqifei.com/index.php。 HEAD方法是一样的,除非该服务器的GET请求无法返回消息体。 POST方法可能涉及到很多东西,如储存或更新数据,或订购产品,或通过提交表单发送电子邮件。这通常是使用服务器端处理,如PHP,Perl和Python等脚本。如果你要上传的文件和在服务器处理数据,你必须使用这个方法。 十二、如何拒绝一些User-Agents? 你可以很容易地阻止User-Agents,如扫描器,机器人以及滥用你服务器的垃圾邮件发送者。 Block download agents if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; } 阻止Soso和有道的机器人: Block some robots if ($http_user_agent ~* Sosospider|YodaoBot) { return 403; } 十三、如何防止图片盗链 图片或HTML盗链的意思是有人直接用你网站的图片地址来显示在他的网站上。最终的结果,你需要支付额外的宽带费用。这通常是在论坛和博客。我强烈建议您封锁,并阻止盗链行为。 Stop deep linking or hot linking location /images/ { valid_referers none blocked www.example.com example.com; if ($invalid_referer) { return 403; } } 例如:重定向并显示指定图片 valid_referers blocked www.example.com example.com; if ($invalid_referer) { rewrite ^/images/uploads.*.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last } 十四、目录限制 你可以对指定的目录设置访问权限。所有的网站目录应该一一的配置,只允许必须的目录访问权限。 通过IP地址限制访问 你可以通过IP地址来限制访问目录/admin/: location /docs/ { block one workstation deny 192.168.1.1; allow anyone in 192.168.1.0/24 allow 192.168.1.0/24; drop rest of the world deny all; } 通过密码保护目录 首先创建密码文件并增加“user”用户: mkdir /usr/local/nginx/conf/.htpasswd/ htpasswd -c /usr/local/nginx/conf/.htpasswd/passwd user 编辑nginx.conf,加入需要保护的目录: Password Protect /personal-images/ and /delta/ directories location ~ /(personal-images/.|delta/.) { auth_basic “Restricted”; auth_basic_user_file /usr/local/nginx/conf/.htpasswd/passwd; } 一旦密码文件已经生成,你也可以用以下的命令来增加允许访问的用户: htpasswd -s /usr/local/nginx/conf/.htpasswd/passwd userName 十五、Nginx SSL配置 HTTP是一个纯文本协议,它是开放的被动监测。你应该使用SSL来加密你的用户内容。 创建SSL证书 执行以下命令: cd /usr/local/nginx/conf openssl genrsa -des3 -out server.key 1024 openssl req -new -key server.key -out server.csr cp server.key server.key.org openssl rsa -in server.key.org -out server.key openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt 编辑nginx.conf并按如下来更新: server { server_name example.com; listen 443; ssl on; ssl_certificate /usr/local/nginx/conf/server.crt; ssl_certificate_key /usr/local/nginx/conf/server.key; access_log /usr/local/nginx/logs/ssl.access.log; error_log /usr/local/nginx/logs/ssl.error.log; } 重启nginx: /usr/local/nginx/sbin/nginx -s reload 十六、Nginx与PHP安全建议 PHP是流行的服务器端脚本语言之一。如下编辑/etc/php.ini文件: Disallow dangerous functions disable_functions = phpinfo, system, mail, exec Try to limit resources Maximum execution time of each script, in seconds max_execution_time = 30 Maximum amount of time each script may spend parsing request data max_input_time = 60 Maximum amount of memory a script may consume (8MB) memory_limit = 8M Maximum size of POST data that PHP will accept. post_max_size = 8M Whether to allow HTTP file uploads. file_uploads = Off Maximum allowed size for uploaded files. upload_max_filesize = 2M Do not expose PHP error messages to external users display_errors = Off Turn on safe mode safe_mode = On Only allow access to executables in isolated directory safe_mode_exec_dir = php-required-executables-path Limit external access to PHP environment safemode_allowed_env_vars = PHP Restrict PHP information leakage expose_php = Off Log all errors log_errors = On Do not register globals for input data register_globals = Off Minimize allowable PHP post size post_max_size = 1K Ensure PHP redirects appropriately cgi.force_redirect = 0 Disallow uploading unless necessary file_uploads = Off Enable SQL safe mode sql.safe_mode = On Avoid Opening remote files allow_url_fopen = Off 十七、如果可能让Nginx运行在一个chroot监狱 把nginx放在一个chroot监狱以减小潜在的非法进入其它目录。你可以使用传统的与nginx一起安装的chroot。如果可能,那使用FreeBSD jails,Xen,OpenVZ虚拟化的容器概念。 十八、在防火墙级限制每个IP的连接数 网络服务器必须监视连接和每秒连接限制。PF和Iptales都能够在进入你的nginx服务器之前阻止最终用户的访问。 Linux Iptables:限制每次Nginx连接数 下面的例子会阻止来自一个IP的60秒钟内超过15个连接端口80的连接数。 /sbin/iptables -A INPUT -p tcp –dport 80 -i eth0 -m state –state NEW -m recent –set /sbin/iptables -A INPUT -p tcp –dport 80 -i eth0 -m state –state NEW -m recent –update –seconds 60 –hitcount 15 -j DROP service iptables save 请根据你的具体情况来设置限制的连接数。 十九:配置操作系统保护Web服务器 像以上介绍的启动SELinux.正确设置/nginx文档根目录的权限。Nginx以用户nginx运行。但是根目录(/nginx或者/usr /local/nginx/html)不应该设置属于用户nginx或对用户nginx可写。找出错误权限的文件可以使用如下命令: find /nginx -user nginx find /usr/local/nginx/html -user nginx 确保你更所有权为root或其它用户,一个典型的权限设置 /usr/local/nginx/html/ ls -l /usr/local/nginx/html/ 示例输出: -rw-r–r– 1 root root 925 Jan 3 00:50 error4xx.html -rw-r–r– 1 root root 52 Jan 3 10:00 error5xx.html -rw-r–r– 1 root root 134 Jan 3 00:52 index.html 你必须删除由vi或其它文本编辑器创建的备份文件: find /nginx -name ‘.?’ -not -name .ht -or -name ‘~’ -or -name ‘.bak’ -or -name ‘.old*’ find /usr/local/nginx/html/ -name ‘.?’ -not -name .ht -or -name ‘~’ -or -name ‘.bak’ -or -name ‘.old*’ 通过find命令的-delete选项来删除这些文件。 二十、限制Nginx连接传出 黑客会使用工具如wget下载你服务器本地的文件。使用Iptables从nginx用户来阻止传出连接。ipt_owner模块试图匹配本地产生的数据包的创建者。下面的例子中只允许user用户在外面使用80连接。 /sbin/iptables -A OUTPUT -o eth0 -m owner –uid-owner vivek -p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT 通过以上的配置,你的nginx服务器已经非常安全了并可以发布网页。可是,你还应该根据你网站程序查找更多的安全设置资料。例如,wordpress或者第三方程序。

KB小秘书 2019-12-02 02:06:56 0 浏览量 回答数 0

问题

第6篇 指针数组字符串(下):报错

kun坤 2020-06-08 11:01:44 4 浏览量 回答数 1
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站