php/js获取客户端mac地址

废话不多讲,直接上代码吧!

<?php  
class MacAddr
{  
    public $returnArray = array();   
    public $macAddr;  

    function __contruct($os_type=null){
        if(is_null($os_type)) $os_type = PHP_OS;  
        switch (strtolower($os_type)){  
        case "linux":  
            $this->forLinux();  
            break;  
        case "solaris":  
            break;  
        case "unix":  
            break;  
        case "aix":  
            break;  
        default:  
            $this->forWindows();  
            break;  
        }  
        $temp_array = array();  
        foreach($this->returnArray as $value ){  
            if(preg_match("/[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f]/i", $value, $temp_array)){  
                $this->macAddr = $temp_array[0];  
                break;  
            }  
        }  
        unset($temp_array);  
        return $this->macAddr;  
    }

    function forWindows(){  
        @exec("ipconfig /all", $this->returnArray);  
        if($this->returnArray)  
            return $this->returnArray;  
        else{  
            $ipconfig = $_SERVER["WINDIR"]."system32ipconfig.exe";  
            if (is_file($ipconfig))  
                @exec($ipconfig." /all", $this->returnArray);  
            else  
                @exec($_SERVER["WINDIR"]."systemipconfig.exe /all", $this->returnArray);  
            return $this->returnArray;  
        }  
    }

    function forLinux(){  
        @exec("ifconfig -a", $this->returnArray);  
        return $this->returnArray;  
    }  
}  

$mac = new MacAddr(PHP_OS);  
echo $mac->macAddr;  
echo "<br />";

// 获取客户端
// linux
$command = "arp -a {$_SERVER['REMOTE_ADDR']}";
echo $command;
echo "<br />";
$result=`{$command}`; 

// windows
$command = "nbtstat -a {$_SERVER['REMOTE_ADDR']}";
echo $command;
echo "<br />";
$result=`{$command}`; 
print_r($result);  
?>  

获取服务端的逻辑没什么大问题,可能会存在权限问题。
获取客户端的时候,可能会比较慢,arp/nbstat命令执行会比较慢。

<script language="JScript" event="OnCompleted(hResult,pErrorObject, pAsyncContext)" for="foo">   
document.forms[0].lbMacAddr.value=unescape(MACAddr);   
</script>  
<script language="JScript" event="OnObjectReady(objObject,objAsyncContext)" for="foo">   
if(objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true && objObject.MACAddress != null && objObject.MACAddress != "undefined") MACAddr = objObject.MACAddress;   
</script>  
<object id="locator" classid="CLSID:76A64158-CB41-11D1-8B02-00600806D9B6"></object>  
<object id="foo" classid="CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223"></object>  
<script language="JScript">   
var service = locator.ConnectServer();   
var MACAddr ;   
var IPAddr ;   
var DomainAddr;   
var sDNSName;   
service.Security_.ImpersonationLevel=3;   
service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration');   
</script>  
<form><input type="text" id='lbMacAddr' name='lbMacAddr' /></form>

只适用于IE浏览器,而且会有告警提示,挺遗憾的。

iptable无法启动

问题:

service iptables status

看到
Firewall is stopped.
执行

service iptables start

没有报错误,但是也没有启动。。
检查:

rpm -e --nodeps iptables

提示:

rpm -e --nodeps iptables

warning: /etc/sysconfig/iptables-config saved as /etc/sysconfig/iptables-config.rpmsave
卸载iptables

yum install iptables

重装iptables之后还是无法启动
###########################################################
查看当前系统加载的模块

lsmod|grep ip_tables
lsmod|grep iptable_filter

如果有,应该能正常启动

查看iptables相关外挂模块

ls -al /lib/modules/`uname -r`/kernel/net/ipv4/netfilter|grep iptable_filter
ls -al /lib/modules/`uname -r`/kernel/net/ipv4/netfilter|grep ip_tables

如果有,就执行:

modprobe ip_tables
modprobe iptable_filter
modprobe iptable_mangle
modprobe iptable_nat

问题应该就解决了。

[转]一个php对象数组转型的BUG

群里说起 php 的数组 key 的类型转换问题,

比如 $a = array(‘123’=>’abc’); var_dump($a); 会发现 key 会变成整数。用 $a[‘123’] 这种方式访问数组的时候,也会先把 key 转换成整数。突然想到能不能构造一个实际 key 为字符串形式的数字的数组,或者整数型属性名的对象(对象内部也是个 hash,也同时支持整数和字符串 key)。试了一些方法没成功。然后看到了这篇东西

http://www.laruence.com/2010/05/26/1541.html
http://syre.blogbus.com/logs/65815204.html

就想到了个构造那样的数组和对象的方法。

$o = new stdClass();
$o->{'123'} = 1;
$a = (array) $o;
var_dump($a);
var_dump(isset($a['123']));
var_dump(isset($a[123]));

$a = array(1,2,3);
$o = (object) $a;
var_dump($o);
var_dump(isset($o->{1}));
var_dump(isset($o->{'1'}));

这样就构造出了正常方式没法访问的数组下标和对象属性*(访问对象属性时会把属性名转成字符串)。

还可以干一件更 BT 的事情,访问对象的私有或保护属性。

class Test {
    private $a = 1;
    protected $b = 2;
    public $c = 3;
}
$o = new Test();
$a = (array) $o;
var_dump($a);
var_dump($a["\0Test\0a"]);
var_dump($a["\0*\0b"]);

Linux下生成csr步骤

Linux下生成csr步骤如下:

# 生成key

openssl genrsa -out server.key 2048

# 生成csr

openssl req -new -key server.key -out server.csr

Country Name (2 letter code) [GB]:CN
State or Province Name (full name) [Berkshire]:Guangdong
Locality Name (eg, city) [Newbury]:Shenzhen
Organization Name (eg, company) [My Company Ltd]:Your Company Name Co., Ltd.
Organizational Unit Name (eg, section) []:Section Name
Common Name (eg, your name or your server’s hostname) []:*.domain.com
Email Address []:services@domain.com
A challenge password []:直接回车
An optional comany name []:直接回车

MySQL 中文网 /proc/kcore是什么文件?

/proc/kcore is like an “alias” for the memory in your computer. Its
size is the same as the amount of RAM you have, and if you read it as
a file, the kernel does memory reads.

如果内核不能识别全部内存,即”ll /proc/kcore”(查看kcore的真实大小:du -h /proc/kcore)后显示的大小不等于实际的物理内存大小,可以用 cat /proc/meminfo 命令来校验.如果所显示的数量与系统的物理内存不同,则在 /boot/grub/grub.conf 文件中添加:
mem=xxM

利用反向代理批量实现https协议访问

最近有一个项目需求,需要为站点增加https访问。

开始只配置了www域名下的https,发现css和js都无法正常加载,原因是https页面,如果加载http协议的内容,会被认为页面不安全,尤其是IE,刷新一下页面就要弹出一次确认,相当烦人。

后来苦逼的把各个子域名都加入了https配置,nginx.conf里写各个子域名都写了一个443的server配置,每新增一个域名,还得copy一份,如果是修改一下站点的配置,还得改两次以上。

后来跟同事讨论,发现使用反向代理,可以快捷现实,配置如下:

sever{
    listen 80;
    sever_name www.hdj.me;
    root /home/webroot/www/;
    index index.php index.html;
    # ...
}
sever{
    listen 80;
    sever_name img.hdj.me;
    root /home/webroot/img/;
    index index.php index.html;
    # ...
}
sever{
    listen 80;
    sever_name static.hdj.me;
    root /home/webroot/static/;
    index index.php index.html;
    # ...
}
sever{
    listen 80;
    sever_name upload.hdj.me;
    root /home/webroot/upload/;
    index index.php index.html;
    # ...
}
server {
    listen 443;
    server_name www.hdj.me img.hdj.me static.hdj.me upload.hdj.me;
    ssl on;
    ssl_certificate /usr/local/nginx/conf/hdj.me.crt;
    ssl_certificate_key /usr/local/nginx/conf/hdj.me.key;

    location /{
        proxy_pass http://127.0.0.1:80;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header SSL '1';
        proxy_redirect http:// https://;
    }
}

这样配置好,访问:
https://www.hdj.me/
https://img.hdj.me/
https://static.hdj.me/
https://upload.hdj.me/
会被反向代理至:
http://www.hdj.me/
http://img.hdj.me/
http://static.hdj.me/
http://upload.hdj.me/
而不需要对各个域名都配置一个443的站点。

修改配置nginx,限制恶意爬虫频率

#全局配置
limit_req_zone $anti_spider zone=anti_spider:10m rate=15r/m;
#某个server中
limit_req zone=anti_spider burst=30 nodelay;
if ($http_user_agent ~* "xxspider|xxbot") {
  set $anti_spider $http_user_agent;
}

超过设置的限定频率,就会给spider一个503。
上述配置详细解释请自行google下,具体的spider/bot名称请自定义。

mysql超出最大连接数原因分析

遇到mysql超出最大连接数,相信不少人第一反应就是查看mysql进程,看有没有慢查询,当然这个做法是完全正确的!
但是很多时候真正的问题不在这里。
今天有遇到同样的问题,一味查看mysql进程和慢查询日志,无果。
后来老大提点了一下,查看一下nginx日志,发现有一两个访问执行时候比较长,然后使用top命令查看了一下服务器负载,惊了,居然超高!
最后发现原来有一台web分流主机挂了,导致另外几台web主机负载增高,从而导致了php-fpm的执行效率降低。
那么这跟mysql有什么关系呢?原因很简单,因为php执行时间过长,mysql连接迟迟未释放,就会导致连接数过多出现。
最后总结:其实很多时候,一个问题的根本原因并不是那么直接的呈现出来,需要自己去跟踪。
老大有一句很实用的话:遇到问题先查日志(mysql、php、nginx等)。

nginx服务器防sql注入/溢出攻击/spam及禁User-agents

在配置文件添加如下字段即可

server {
## 禁SQL注入 Block SQL injections
set $block_sql_injections 0;
if ($query_string ~ "union.*select.*\(") {
set $block_sql_injections 1;
}
if ($query_string ~ "union.*all.*select.*") {
set $block_sql_injections 1;
}
if ($query_string ~ "concat.*\(") {
set $block_sql_injections 1;
}
if ($block_sql_injections = 1) {
return 444;
}

## 禁掉文件注入
set $block_file_injections 0;
if ($query_string ~ "[a-zA-Z0-9_]=http://") {
set $block_file_injections 1;
}
if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") {
set $block_file_injections 1;
}
if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {
set $block_file_injections 1;
}
if ($block_file_injections = 1) {
return 444;
}

## 禁掉溢出攻击
set $block_common_exploits 0;
if ($query_string ~ "(<|%3C).*script.*(>|%3E)") {
set $block_common_exploits 1;
}
if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") {
set $block_common_exploits 1;
}
if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") {
set $block_common_exploits 1;
}
if ($query_string ~ "proc/self/environ") {
set $block_common_exploits 1;
}
if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") {
set $block_common_exploits 1;
}
if ($query_string ~ "base64_(en|de)code\(.*\)") {
set $block_common_exploits 1;
}
if ($block_common_exploits = 1) {
return 444;
}

## 禁spam字段
set $block_spam 0;
if ($query_string ~ "\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b") {
set $block_spam 1;
}
if ($query_string ~ "\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b") {
set $block_spam 1;
}
if ($query_string ~ "\b(ambien|blue\spill|cialis|cocaine|ejaculation|erectile)\b") {
set $block_spam 1;
}
if ($query_string ~ "\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b") {
set $block_spam 1;
}
if ($block_spam = 1) {
return 444;
}

## 禁掉user-agents
set $block_user_agents 0;

# Don’t disable wget if you need it to run cron jobs!
#if ($http_user_agent ~ "Wget") {
# set $block_user_agents 1;
#}

# Disable Akeeba Remote Control 2.5 and earlier
if ($http_user_agent ~ "Indy Library") {
set $block_user_agents 1;
}

# Common bandwidth hoggers and hacking tools.
if ($http_user_agent ~ "libwww-perl") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "GetRight") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "GetWeb!") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "Go!Zilla") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "Download Demon") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "Go-Ahead-Got-It") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "TurnitinBot") {
set $block_user_agents 1;
}
if ($http_user_agent ~ "GrabNet") {
set $block_user_agents 1;
}

if ($block_user_agents = 1) {
return 444;
}
}

说明:防sql注入/溢出攻击/spam采用禁掉URL中包含的字段实现,请根据需要合理添加
返回444,是完全不回应客户端,比403更加非常节省系统资源