apache日志分离组件cronolog
1.1 概述
apache默认的日志都会记录到一个文件内
如果访问量过多,时间过长,将导致日志堆积,文件变大,影响apache的性能
cronolog是一个用于日志切分的软件,使用管道把输入定位到其他路径保存
1.2 安装
wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
tar xcvf cronolog-1.6.2.tar.gz
cd cronolog-1.6.2
sudo ./configure -–prefix=%INSTALL_DIR%
sudo make install
1.3 使用
修改apache的日志记录
CustomLog “|%INSTALL_DIR%/cronolog %APACHE_HOME%/apache/logs/cronolog/%Y/%m/%d/%H_access_log” combined
ErrorLog “|%INSTALL_DIR%/cronolog %APACHE_HOME%/logs/cronolog/%Y/%m/%d/error_log”
然后需要reload下apache
sudo service apache restart
接下来可以在对应的logs/cronolog里面找到分离开的日志
1.4 Cronolog的参书规则
Specifier |
Description |
%% | a literal % character |
%n | a new-line character |
%t | a horizontal tab character |
Time fields | |
%H | hour (00..23) |
%I | hour (01..12) |
%p | the locale’s AM or PM indicator |
%M | minute (00..59) |
%S | second (00..61, which allows for leap seconds) |
%X | the locale’s time representation (e.g.: “15:12:47”) |
%Z | time zone (e.g. GMT), or nothing if the time zone cannot be determined |
Date fields | |
%a | the locale’s abbreviated weekday name (e.g.: Sun..Sat) |
%A | the locale’s full weekday name (e.g.: Sunday .. Saturday) |
%b | the locale’s abbreviated month name (e.g.: Jan .. Dec) |
%B | the locale’s full month name, (e.g.: January .. December) |
%c | the locale’s date and time (e.g.: "Sun Dec 15 14:12:47 GMT 1996") |
%d | day of month (01 .. 31) |
%j | day of year (001 .. 366) |
%m | month (01 .. 12) |
%U | week of the year with Sunday as first day of week (00..53, where week 1 is the week containing the first Sunday of the year) |
%W | week of the year with Monday as first day of week (00..53, where week 1 is the week containing the first Monday of the year) |
%w | day of week (0 .. 6, where 0 corresponds to Sunday) |
%x | locale’s date representation (e.g. today in Britain: “15/12/96”) |
%y | year without the century (00 .. 99) |
%Y | year with the century (1970 .. 2038) |
一段代码说优化[php]
这是原始代码
- <?
- echo “Hello “.$_GET[‘name’].“!”;
- ?>
这段代码是大体没有问题的,但是存在一些细节
1. 开头使用<? 没有使用<?php 不规范如果php.ini里面没有开启的话 此段代码将无法执行
2. $_GET[‘name’]没有做前置判断是否存在。如果url里面没有这个参数。用户进来很有可能看到报警信息,不友好
3. “(双引号)和'(单引号)的区别是单引号不会对里面的内容进行匹配转义。
比如
- $a=‘123’;
- echo ‘a$a’;
会输出a$a而非a123。
在上面的代码中不需要进行这种操作,所以用'(单引号)更好,解释器不再检测变量替换,速度更快
4. 这段代码的目的是打印出字符串。字符串中间的连接符可以改为,(逗号) 让echo顺序打印,不再执行字符串的连接操作
5. 输出没有转义,存在跨站漏洞,忘了,呵呵。 感谢老大指正~(@见素)
最后的代码如下
- <?php
- if(isset($_GET[‘name’])) echo ‘Hello ‘,htmlspecialchars($_GET[‘name’]),‘!‘;
- ?>
ARP攻击和防御
去实习前还是得找点事情做.于是决定写下这篇文章.
一.ARP概述
1) IP数据包常通过以太网发送。但是以太网设备并不识别32位IP地址:它们是以48位以太网地址(就是所谓的MAC)传输
以太网数据包的。因此,必须把IP目的地址转换成以太网网目的地址。在这两种地址之间存在着某种静态的或算法的映
射,常常需要查看一张表。地址解析协议(Address Resolution Protocol,ARP)就是用来确定这些映象的协议
2) ARP工作时,会向整个子网广播信息,ARP发送分两步。第一步request,第二步reply。第一步的时候,需要查询的主
机会询问整个子网,谁有我需要的ip?如果有主机拥有这个ip,目的主机就发送一个回应消息,并包含自己的MAC地址。
查询主机收到后便会更新自己的ARP表
下面用抓包工具给大家说明下,抓包工具我使用的是Wireshark,过滤只显示arp包
根据上图 可以很明显的看到 首先QuantaCo_e3:77:0a (00:1e:68:e3:77:0a)这台电脑广播信息谁有192.168.0.3。请求包的最后含有请求主机的ip和mac,还有询问的ip
接着主机AsustekC_94:5e:76 (00:26:18:94:5e:76) 回应给我们的QuantaCo_e3:77:0a (00:1e:68:e3:77:0a) 并带上了自己的mac地址00:26:18:94:5e:76告诉我们它有192.168.0.3
然后看看我们电脑的ARP表,已经出现他了
之后如果我想和192.168.0.3通信就会使用00-26-18-94-5e-76这个MAC地址和目标主机进行通信
二.ARP欺骗
刚才说到了请求主机是向整个内网发送的请求,然后目标主机回应。这样就出现一个问题。如果我其实并不是目标主机
呢?于是我发送发布虚假的ARP报文,然后我就可以扮演某些机器,或者顺便对数据流进行简单的修改。
1) 典型的路由欺骗
一个正常的局域网内应该像这样 ABC如果想和外网通信 都需通过路由器出去
但是如果A不停向BC发送ARP报文 包里面封装上路由的IP和自己的MAC.把自己伪装成路由
这样BC都会认为A是路由器,于是傻傻得把数据都交给A了..与此同时路由也会发送自己正确的ARP..
如果A不把包再转发出去..结果就是BC端端徐徐不能上网,或者很难才能联上外网
就变成这样了 A拦截到所有的通信包,并可以进行分析
1.1) 代码实现
我用java实现了一个很简单的ARP攻击例子,java不能操作底层网络包.所以我们需要一个
其他的辅助工具jpcap [download id=”32″] 这个东西因为是使用jni调用的,以下的以win为例子..linux需要改下包
安装的时候注意2点:
1. 请先安装winpcap或者ubuntu
2.使用32位的jdk或者jre 否则它都不会工作
核心是这些
arp.sender_hardaddr=device.mac_address;
arp.sender_protoaddr=gateway.getAddress();
改变报文ip为路由的ip 改变mac为我自己的mac
伪装路由器向整个局域网发送谁有192.168.0.5请告诉192.168.0.1
目标主机收到后.便会改变他自己电脑上的arp表.把192.168.0.1的mac对应成我的电脑的
结果就是之后的请求他都认为我是路由器从而我可以得到他发送的报文
示例代码里面拦截所有80端口,,可以看到被攻击主机发送的http请求..cookie信息当然也在啦..
然后我们可以..
源码: [download id=”33″]
2) 针对服务器的ARP攻击
这类攻击常见于服务器群, vps群..内网上的主机被同网段的攻击主机攻陷..结果是您的网站不
定期被跳转到其他网站或者出现其他很奇怪的页面
原理和刚才一样.但是这类软件同时还有构造伪装的http包的功能.会把服务器正常的包给拦截下
转而发送自己的包给客户端.于是造成刚才说的现象..这类攻击比较隐蔽..而且在国内主机里面都比较普片
三.ARP防御
1) 手动绑定网关
ARP表分为两种 动态的和静态的 用ARP协议进行更新的都是动态的
但是我们通过可以手动绑定ARP表的方式 静态的arp不会受影响
2) 使用软件
其实原理和上面的差不多 最好的解决办法就是绑定静态arp..
3) 有带保护功能的路由
但是如果是路由arp欺骗也基本无效..因为被欺骗的是其他内网用户 不是路由
综上 最简单方便的办法就是用arp –s 绑定静态路由
文中资料下载:
库: [download id=”32″]
源码: [download id=”33″]
可以去实习了!
经过四天的面试后,终于可以去实习了!
面试的最大感觉就是..
得专一..哎. 很多基础性的东西答不上来..
基础需重视! 就如之前某说的 基础决定了你能走多远
感谢所有朋友,同学,面试官.
中途还得回来一下.
一直努力吧~
去之前还得先把学校这个选题系统写完..还差一点.
写完之后还是开源..
线程安全和一条sql语句引起的思考(二)
接着上次的文章讨论php线程安全
当然不仅仅针对php
范大牛和我争了一下..不过说来问题是确实存在的
那怎么解决呢
其实解决方式有很多种
1. 把运算放在php里面
代码如下:
//如果大于0 就减100 if($money>0){ $money -=100; $res=mysql_query("UPDATE `test` SET `k` = $money where id=1"); echo "减了!"; }else{ echo "没做操作"; } 结果:这样虽然会做重复的sql更新操作 但是结果都是正确的值
2.加上限定where
3.使用事务来控制这个地方我想到其实就是传说中的事务控制但是使用的时候又发现了问题
首先必须把mysql的存储方式改成innodb,5.5默认已经是这个了
只有这个才支持事务的控制来看看第一次写的版本
<? $host="127.0.0.1"; $user="root"; $passwd="123"; mysql_connect($host,$user,$passwd); mysql_select_db("test"); mysql_query("set names utf8"); mysql_query("BEGIN"); //查询是否是大于0的 $res=mysql_query("select * from test where id=1 and k=100"); $res=mysql_fetch_array($res); $money=$res['k']; //如果大于0 就减100 if($money>0){ $res=mysql_query("UPDATE `test` SET `k` = `k`-100 where id=1"); $err_msg = mysql_error(); if($err_msg!=""){ echo "回滚了"; mysql_query("ROLLBACK"); } else{ echo "提交了"; mysql_query("COMMIT"); } }else{ echo "没做操作"; } ?>
结果是错误的!
和之前的运行效果一样,事务并没有进行处理
为什么呢,一直没搞懂了.难道事务是不管脏数据的?
第二个线程读到的数据已经被第一个改掉了.按理说应该会抛错啊?
直到今天! 终于找到原因了
原来在数据库里面,事务的隔离是分级别的
要加上这一句..
mysql_query(“SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
;”);
加在mysql_query(“BEGIN“); 后面就可以了
事务的控制是人为触发.抛错只会在sql执行中
所以其实那个rollback是多余的
不过这样的结果是效率降低
其他的数据库操作需要等待前一个commit之后才能进行
然后还有其他的办法,就是锁行
$res=mysql_query(“select * from test where id=1 and k=100 for update“);
这样改动后其他的必须在执行了update之后才能进行读取,就保证了读取的不是脏数据
参考资料:
线程安全和一条sql语句引起的思考(一)
这篇文章发布在php分类
因为主要是讨论php的线程安全问题,但是如下遇到的问题在其他的编程环境中也会遇到
首先您肯定会问php官网不是发布过么? 分为线程安全版本和非安全版本
但是既然是线程安全,那言下之意每个进程间相互应该不受干扰.
难道是指所有的进程都需要排队?一个一个的执行
于是抱着问题进行了如下的尝试
<? $host="127.0.0.1"; $user="root"; $passwd="123"; mysql_connect($host,$user,$passwd); mysql_select_db("test"); mysql_query("set names utf8"); //查询是否是大于0的 $res=mysql_query("select * from test where id=1 and k=100"); $res=mysql_fetch_array($res); $money=$res['k']; //如果大于0 就减100 if($money>0){ $res=mysql_query("UPDATE `test` SET `k` = `k`-100 where id=1"); echo "减了!"; }else{ echo "没做操作"; } ?>
代码如上面所示
就是判断k,如果等于100,那么则减去100
数据库test里面只有一个表test
里面的字段为id int k int
只有一条记录
id=1 k=100
好 让我们执行上面的语句
结果一般说来k就会变成0了
但是实际上,问题来了
如果中间的操作耗费了大量的时间,导致延迟更新了
结果又怎样了?
<? $host="127.0.0.1"; $user="root"; $passwd="123"; mysql_connect($host,$user,$passwd); mysql_select_db("test"); mysql_query("set names utf8"); //查询是否是大于0的 $res=mysql_query("select * from test where id=1 and k=100"); $res=mysql_fetch_array($res); $money=$res['k'];
//模拟延迟 这里做一个for循环 模拟中间处理了很多操作
for($i=0;$i<9999999;$i++){
}
//如果大于0 就减100
if($money>0){
$res=mysql_query(“UPDATE `test` SET `k` = `k`-100 where id=1“);
echo “减了!“;
}else{
echo “没做操作“;
}
?>
然后再打开浏览器 重复刷新几次
这个时候结果就不一定是0了! 有可能是-100 –200
视刷新情况而定
而且不管你用所谓的线程安全版本也是同样的结果
为什么么?如果你知道java单例模型中其中的synchronize你应该就明白了
看看这个图
其中左边是线程1 右边是线程2
从上至下假设为我们的线程执行顺序 线程1先执行了
请注意绿色划线部分
线程2得到的$money的值是100!
因为这个时候线程1的update尚未执行
于是当2执行到后面的时候也进行了一次减法
于是就会出现-100 -200的情况
甚至不加for循环,快速刷新一下也会出现这个问题
这说明php的执行并非线程安全,那个所谓的线程安全版本根本就不是这个意思
想来也可以理解,如果真的线程安全了,执行效率很降很多很多很多,因为第二个线程必须等待第一个释放了才能执行
这篇文章先写到这里,下一篇会告诉大家如何解决以及新发生的问题
更新一下cdutkvb
之前的客户端因为域名过期了
不能用了
请下载新的客户端版本号是1.03
功能还是一样的 可以把课表直接存到手机的日程表里面
支持所有带java功能的手机
输入教务处的用户和密码后点确认就可以
插入的过程中需要你不断按确认..
已知Bug: 索爱大部分机型时间错误
android版的HTC大部分的通过了测试 其他机型未知
J2me版下载地址: [download id=”30″]
Android版下载地址: [download id=”31″]
新浪真小气
java socks5 proxy
这个是继上次的httpproxy后的另一个代理服务器的实现.
协议是socks v5版本
但是只实现了CMD的connect部分.
还有bind和UDP没有实现.
经过测试使用完全没有问题
这里提供源代码和jar包
默认打开的端口是1080..
没有做配置文件载入的功能..
这个socks5只实现了透明代理..没有实现加密..
所以呢.. 还是翻墙不能
然后下一步做一个支持加密的代理..
jar runnable [download id=”29″]
source code [download id=”28″]
用java做的HTTP/S代理服务器
最近用java写了一个代理服务器
HTTP的代理原理很简单
正常情况下 没有用代理 比如你要访问http://haku.hk/test.html
浏览器会向3haku.net主机发送如下的请求
- GET /test.html HTTP/1.0
如果使用了代理服务器 比如你使用了localhost 端口92
浏览器会向localhost的92端口发送如下报头
- GET http://3haku.net/test.html HTTP/1.0
这个时候代理服务器收到了请求 然后就吧http://haku.hk/test.html解析出host和path
然后再向3haku.net发送请求 然后吧收到的信息组装或者直接发送回客户机
这个过程是明文的 也就是说任何一个经过向代理服务器的网络 都可以看到你发送消息和回应
如果要使传输加密 可以用SSL
这个代码里面http代理测试过是可以用的 部分封装了HTTP协议
还封装了https的客户端连接,但是没测试,不晓得原因.
测试的话把main里面改成这个
- HTTPProxyServer ss=new SecureProxyServer(Integer.parseInt(argv[0]));
下一步打算做个socks5的代理服务器..
源码在此 [download id=”27″]
SSL参考 http://onjava.com/pub/a/onjava/2001/05/03/java_security.html