分类: Linux

解决vsftpd登陆慢卡的问题

没有评论

2013 年 10 月 30 日 at 下午 9:54分类:Linux

在使用vsftpd的过程中,一直以来都有一个问题就是在ftp用户登陆验证的时候总是很慢,最长的时候可能会有一分多钟。

换过各种vsftp的配置方式虚拟用户,使用MySQL、文本等等,都没有根本的解决。今天给一台测试机器装vsftp,再次遇到这个问题,在历经千辛万苦之后终于找的了其中的原因。

修改服务器上的/etc/resolv.conf令其内容只有类似

nameserver 192.81.133.229
nameserver 114.114.114.114

出现问题的机器的resolv.conf中总是含有localhost或者127.0.0.1这样的地址。也就是说当客户端连接服务器时,服务器会执行一个DNS查找,来确认域名,如果所用DNS解析不到,会等到超时为止。

用PHP编写daemon process

没有评论

2013 年 07 月 30 日 at 下午 10:26分类:Linux | PHP

php从5开始,他的使用场景早已不限于处理web请求,而可以实现诸多服务化的使用场景。
从php的架构体系来说,php分为三个层次:sapi、php core和zend engine。
php core本身和web没有任何耦合,php通过sapi与其它应用程序通信,例如mod_php就是为apache编写的sapi实现,同样,fpm是一个基于fastcgi协议的sapi实现,这些sapi都是与web server配合用于处理web请求的。但是也有许多sapi与web无关,例如cli sapi可以使得在命令行环境下直接执行php,embed sapi可以将php嵌入其它语言(如Lua)那样。这里我并不打算详细讨论php的架构体系和sapi的话题,只是说明从架构体系角度目前的php早已被设计为支持各种环境,而非为web独有。

除了架构体系的支持外,php丰富的扩展模块也为php在不同环境发挥作用提供了后盾,例如本文要提到的pcntl(进程)模块和posix(信号)模块配合可以实现基本的进程管理、信号处理等操作系统级别的功能,而sockets模块可以使php具有socket通信的能力。因此php完全可以用于编写类似于shell或perl或python常做的工具性脚本,甚至是具有server性质的daemon process。

为了展示php如何编写daemon server,我用php编写了一个简单的http server,这个server以daemon process的形式运行。当然,为了把重点放在如何使用php编写daemon,我没有为这个http server实现具体业务逻辑,但它可以监听指定端口,接受http请求并返回给客户端一条固定的文本,整个过程通过socket实现,全部由php编写而成。

<?php
function handle_http_request($address, $port)
{
    $max_backlog = 16;
    $res_content = "HTTP/1.1 200 OK
        Content-Length: 15
        Content-Type: text/plain; charset=UTF-8

        PHP HTTP Server";
    $res_len = strlen($res_content);

    //Create, bind and listen to socket
    if(($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
    {
        echo "Create socket failed!\n";
        exit;
    }   

    if((socket_bind($socket, $address, $port)) === FALSE)
    {
        echo "Bind socket failed!\n";
        exit;
    }

    if((socket_listen($socket, $max_backlog)) === FALSE)
    {
        echo "Listen to socket failed!\n";
        exit;
    }

    //Loop
    while(TRUE)
    {
        if(($accept_socket = socket_accept($socket)) === FALSE)
        {
            continue;
        }
        else
        {
            socket_write($accept_socket, $res_content, $res_len);   
            socket_close($accept_socket);
        }
    }
}

//以daemon方式运行
function run()
{
    if(($pid1 = pcntl_fork()) === 0)
    //第一个子进程
    {
        posix_setsid(); //子进程1变为session leader,让子进程2与其祖先分离

        if(($pid2 = pcntl_fork()) === 0)
        //第二个子进程,以daemon方式跑他的父进程托管给了init
        {
            //此段代码调用个可以替换成你的代码 让你的代码也运行以daemon
            handle_http_request('www.codinglabs.org', 9999); 
        }
        else
        {
            //子进程退出
            exit;
        }
    }
    else
    {
        //等待子进程处理状态
        pcntl_wait($status);
    }
}

run();

?>

上面的代码分为两段,第一段是socket的过程,无非就是一些监听端口,接收客户端连接,处理连接,返回数据的过程;第二段是进程处理的过程,run函数负责将整个程序变为daemon process,方法和Unix环境下C的方法很类似,通过两次fork,第一次fork后调用setsid将子进程1变为session leader,这样就可以让子进程2与其祖先detach,即使祖先进程结束了它也会继续运行(托孤给init进程)。这个run函数可以用在我们自己的其他功能中,只需要修改其中的一行代码即可。

Git常用命令备忘

没有评论

2013 年 07 月 28 日 at 下午 10:26分类:Linux

1.Git配置

git config --global user.name "robbin"   
git config --global user.email "fankai@gmail.com"
git config --global color.ui true
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global core.editor "mate -w"    # 设置Editor使用textmate

用户的git配置文件~/.gitconfig

2.Git常用命令

2.1 查看、添加、提交、删除、找回,重置修改文件

git help <command>  # 显示command的help
git show            # 显示某次提交的内容
git show $id

git co  -- <file>   # 抛弃工作区修改
git co  .           # 抛弃工作区修改

git add <file>      # 将工作文件修改提交到本地暂存区
git add .           # 将所有修改过的工作文件提交暂存区

git rm <file>       # 从版本库中删除文件
git rm <file> --cached  # 从版本库中删除文件,但不删除文件

git reset <file>    # 从暂存区恢复到工作文件
git reset -- .      # 从暂存区恢复到工作文件
git reset --hard    # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改

git ci <file>
git ci .
git ci -a           # 将git add, git rm和git ci等操作都合并在一起做
git ci -am "some comments"
git ci --amend      # 修改最后一次提交记录

git revert <$id>    # 恢复某次提交的状态,恢复动作本身也创建了一次提交对象
git revert HEAD     # 恢复最后一次提交的状态

2.2 查看文件diff

git diff <file>     # 比较当前文件和暂存区文件差异
git diff
git diff <$id1> <$id2>   # 比较两次提交之间的差异
git diff <branch1>..<branch2> # 在两个分支之间比较 
git diff --staged   # 比较暂存区和版本库差异
git diff --cached   # 比较暂存区和版本库差异
git diff --stat     # 仅仅比较统计信息

2.3 查看提交记录

git log
git log <file>      # 查看该文件每次提交记录
git log -p <file>   # 查看每次详细修改内容的diff
git log -p -2       # 查看最近两次详细修改内容的diff
git log --stat      # 查看提交统计信息

3.Git 本地分支管理

3.1 查看、切换、创建和删除分支

git br -r           # 查看远程分支
git br <new_branch> # 创建新的分支
git br -v           # 查看各个分支最后提交信息
git br --merged     # 查看已经被合并到当前分支的分支
git br --no-merged  # 查看尚未被合并到当前分支的分支

git co <branch>     # 切换到某个分支
git co -b <new_branch> # 创建新的分支,并且切换过去
git co -b <new_branch> <branch>  # 基于branch创建新的new_branch

git co $id          # 把某次历史提交记录checkout出来,但无分支信息,切换到其他分支会自动删除
git co $id -b <new_branch>  # 把某次历史提交记录checkout出来,创建成一个分支

git br -d <branch>  # 删除某个分支
git br -D <branch>  # 强制删除某个分支 (未被合并的分支被删除的时候需要强制)

3.2 分支合并和rebase

git merge <branch>               # 将branch分支合并到当前分支
git merge origin/master --no-ff  # 不要Fast-Foward合并,这样可以生成merge提交

git rebase master <branch>       # 将master rebase到branch,相当于:
git co <branch> && git rebase master && git co master && git merge <branch>

3.3 Git补丁管理(方便在多台机器上开发同步时用)

git diff > ../sync.patch         # 生成补丁
git apply ../sync.patch          # 打补丁
git apply --check ../sync.patch  # 测试补丁能否成功

3.4 Git暂存管理

git stash                        # 暂存
git stash list                   # 列所有stash
git stash apply                  # 恢复暂存的内容
git stash drop                   # 删除暂存区

3.5 Git远程分支管理

git pull                         # 抓取远程仓库所有分支更新并合并到本地
git pull --no-ff                 # 抓取远程仓库所有分支更新并合并到本地,不要快进合并
git fetch origin                 # 抓取远程仓库更新
git merge origin/master          # 将远程主分支合并到本地当前分支
git co --track origin/branch     # 跟踪某个远程分支创建相应的本地分支
git co -b <local_branch> origin/<remote_branch>  # 基于远程分支创建本地分支,功能同上

git push                         # push所有分支
git push origin master           # 将本地主分支推到远程主分支
git push -u origin master        # 将本地主分支推到远程(如无远程主分支则创建,用于初始化远程仓库)
git push origin <local_branch>   # 创建远程分支, origin是远程仓库名
git push origin <local_branch>:<remote_branch>  # 创建远程分支
git push origin :<remote_branch>  #先删除本地分支(git br -d <branch>),然后再push删除远程分支

3.6 Git远程仓库管理

git remote -v                    # 查看远程服务器地址和仓库名称
git remote show origin           # 查看远程服务器仓库状态
git remote add origin git@github:robbin/robbin_site.git         # 添加远程仓库地址
git remote set-url origin git@github.com:robbin/robbin_site.git # 设置远程仓库地址(用于修改远程仓库地址)
git remote rm <repository>       # 删除远程仓库

3.7 创建远程仓库

git clone --bare robbin_site robbin_site.git  # 用带版本的项目创建纯版本仓库
scp -r my_project.git git@git.csdn.net:~      # 将纯仓库上传到服务器上

mkdir robbin_site.git && cd robbin_site.git && git --bare init # 在服务器创建纯仓库
git remote add origin git@github.com:robbin/robbin_site.git    # 设置远程仓库地址
git push -u origin master                                      # 客户端首次提交
git push -u origin develop  # 首次将本地develop分支提交到远程develop分支,并且track

git remote set-head origin master   # 设置远程仓库的HEAD指向master分支

SSH的简单运用

没有评论

2013 年 07 月 27 日 at 下午 5:19分类:Linux

1.绑定本地端口
既然SSH可以传送数据,那么我们可以让那些不加密的网络连接,全部改走SSH连接,从而提高安全性。
假定我们要让8080端口的数据,都通过SSH传向远程主机,命令就这样写:

$ ssh -D 8080 user@host

SSH会建立一个socket,去监听本地的8080端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果8080端口原来是一个不加密端口,现在将变成一个加密端口。

2.本地端口转发
有时,绑定本地端口还不够,还必须指定数据传送的目标主机,从而形成点对点的”端口转发”。为了区别后文的”远程端口转发”,我们把这种情况称为”本地端口转发”(Local forwarding)。
假定host1是本地主机,host2是远程主机。由于种种原因,这两台主机之间无法连通。但是,另外还有一台host3,可以同时连通前面两台主机。因此,很自然的想法就是,通过host3,将host1连上host2。
我们在host1执行下面的命令:

 $ ssh -L 2121:host2:21 host3

命令中的L参数一共接受三个值,分别是”本地端口:目标主机:目标主机端口”,它们之间用冒号分隔。这条命令的意思,就是指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。
这样一来,我们只要连接host1的2121端口,就等于连上了host2的21端口。

$ ftp localhost:2121

“本地端口转发”使得host1和host3之间仿佛形成一个数据传输的秘密隧道,因此又被称为”SSH隧道”。

3.本地端口转发
既然”本地端口转发”是指绑定本地端口的转发,那么”远程端口转发”(remote forwarding)当然是指绑定远程端口的转发。
还是接着看上面那个例子,host1与host2之间无法连通,必须借助host3转发。但是,特殊情况出现了,host3是一台内网机器,它可以连接外网的host1,但是反过来就不行,外网的host1连不上内网的host3。这时,”本地端口转发”就不能用了,怎么办?
解决办法是,既然host3可以连host1,那么就从host3上建立与host1的SSH连接,然后在host1上使用这条连接就可以了。
我们在host3执行下面的命令:

$ ssh -R 2121:host2:21 host1

R参数也是接受三个值,分别是”远程主机端口:目标主机:目标主机端口”。这条命令的意思,就是让host1监听它自己的2121端口,然后将所有数据经由host3,转发到host2的21端口。由于对于host3来说,host1是远程主机,所以这种情况就被称为”远程端口绑定”。
绑定之后,我们在host1就可以连接host2了:

$ ftp localhost:2121

这里必须指出,”远程端口转发”的前提条件是,host1和host3两台主机都有sshD和ssh客户端。

原文:http://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html

SSH原理与运用

没有评论

2013 年 07 月 27 日 at 下午 2:25分类:Linux

SSH是每一台Linux电脑的标准配置。随着Linux设备从电脑逐渐扩展到手机、外设和家用电器,SSH的使用范围也越来越广。不仅程序员离不开它,很多普通用户也每天使用。SSH具备多种功能,可以用于很多场合。有些事情,没有它就是办不成。本文是我的学习笔记,总结和解释了SSH的常见用法,希望对大家有用。虽然本文内容只涉及初级应用,较为简单,但是需要读者具备最基本的”Shell知识”和了解”公钥加密”的概念。

一、什么是SSH?
简单说,SSH是一种网络协议,用于计算机之间的加密登录。 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露。 最早的时候,互联网通信都是明文通信,一旦被截获,内容就暴露无疑。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的标准配置。 需要指出的是,SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。本文针对的实现是OpenSSH,它是自由软件,应用非常广泛。 此外,本文只讨论SSH在Linux Shell中的用法。如果要在Windows系统中使用SSH,会用到另一种软件PuTTY,这需要另文介绍。

二、最基本的用法
SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。

$ ssh user@host

如果本地用户名与远程用户名一致,登录时可以省略用户名。

$ ssh host

SSH的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口。

$ ssh -p 2222 user@host

上面这条命令表示,ssh直接连接远程主机的2222端口。

三、中间人攻击
SSH之所以能够保证安全,原因在于它采用了公钥加密。
整个过程是这样的:
(1)远程主机收到用户的登录请求,把自己的公钥发给用户。
(2)用户使用这个公钥,将登录密码加密后,发送回来。
(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。 可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的”中间人攻击”(Man-in-the-middle attack)。
SSH协议是如何应对的呢?

四、口令登录
如果你是第一次登录对方主机,系统会出现下面的提示:

$ ssh user@host
  The authenticity of host 'host (12.18.429.21)' can't be established.
  RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
  Are you sure you want to continue connecting (yes/no)?

这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?
所谓”公钥指纹”,是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。
很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。
假定经过风险衡量以后,用户决定接受这个远程主机的公钥。

   Are you sure you want to continue connecting (yes/no)? yes

系统会出现一句提示,表示host主机已经得到认可。

   Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.

然后,会要求输入密码。

  Password: (enter password)

如果密码正确,就可以登录了。
当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。

五、公钥登录
使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。
所谓”公钥登录”,原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。
这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:

$ ssh-keygen

运行上面的命令以后,系统会出现一系列提示,可以一路回车。其中有一个问题是,要不要对私钥设置口令(passphrase),如果担心私钥的安全,这里可以设置一个。
运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥。
这时再输入下面的命令,将公钥传送到远程主机host上面:

$ ssh-copy-id user@host

好了,从此你再登录,就不需要输入密码了。
如果还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,检查下面几行前面”#”注释是否取掉。

   RSAAuthentication yes
   PubkeyAuthentication yes
   AuthorizedKeysFile .ssh/authorized_keys

然后,重启远程主机的ssh服务。

$ /etc/init.d/ssh restart

六、authorized_keys文件
远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。这里不使用上面的ssh-copy-id命令,改用下面的命令,解释公钥的保存过程:

$ ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

这条命令由多个语句组成,依次分解开来看:
(1)”$ ssh user@host”,表示登录远程主机;
(2)单引号中的mkdir .ssh && cat >> .ssh/authorized_keys,表示登录后在远程shell上执行的命令:
(3)”$ mkdir -p .ssh”的作用是,如果用户主目录中的.ssh目录不存在,就创建一个;
(4)’cat >> .ssh/authorized_keys’ < ~/.ssh/id_rsa.pub的作用是,将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾。写入authorized_keys文件后,公钥登录的设置就完成了。 原文:http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html

一个经典实用的iptables shell脚本(转)

没有评论

2013 年 07 月 04 日 at 下午 9:42分类:Linux

这个iptables脚本不错,很实用,根据实际应用改一下就可以自己用。源代码如下:

#!/bin/sh
#
modprobe ipt_MASQUERADE
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
iptables -F
iptables -t nat -F
iptables -X
iptables -t nat -X
###########################INPUT键###################################

iptables -P INPUT DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 110,80,25 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.0/24 --dport 139 -j ACCEPT
#允许内网samba,smtp,pop3,连接
iptables -A INPUT -i eth1 -p udp -m multiport --dports 53 -j ACCEPT
#允许dns连接
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p gre -j ACCEPT
#允许外网vpn连接
iptables -A INPUT -s 192.186.0.0/24 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i ppp0 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP
#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃
iptables -A INPUT -s 192.186.0.0/24 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP
#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃
iptables -A INPUT -p icmp -m limit --limit 3/s -j LOG --log-level INFO --log-prefix "ICMP packet IN: "
iptables -A INPUT -p icmp -j DROP
#禁止icmp通信-ping 不通
iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE
#内网转发
iptables -N syn-flood
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -I syn-flood -p tcp -m limit --limit 3/s --limit-burst 6 -j RETURN
iptables -A syn-flood -j REJECT
#防止SYN攻击 轻量
#######################FORWARD链###########################
iptables -P FORWARD DROP
iptables -A FORWARD -p tcp -s 192.168.0.0/24 -m multiport --dports 80,110,21,25,1723 -j ACCEPT
iptables -A FORWARD -p udp -s 192.168.0.0/24 --dport 53 -j ACCEPT
iptables -A FORWARD -p gre -s 192.168.0.0/24 -j ACCEPT
iptables -A FORWARD -p icmp -s 192.168.0.0/24 -j ACCEPT
#允许 vpn客户走vpn网络连接外网
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq通信
iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq通信
iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -m time --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -m time --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的13:30-20:30禁止QQ通信
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq网页
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -m time --timestart 13:00 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的13:30-20:30禁止QQ网页
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "ay2000.net" -j DROP
iptables -I FORWARD -d 192.168.0.0/24 -m string --string "宽频影院" -j DROP
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "色情" -j DROP
iptables -I FORWARD -p tcp --sport 80 -m string --string "广告" -j DROP
#禁止ay2000.net,宽频影院,色情,广告网页连接 !但中文 不是很理想
iptables -A FORWARD -m ipp2p --edk --kazaa --bit -j DROP
iptables -A FORWARD -p tcp -m ipp2p --ares -j DROP
iptables -A FORWARD -p udp -m ipp2p --kazaa -j DROP
#禁止BT连接
iptables -A FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 24
#######################################################################
sysctl -w net.ipv4.ip_forward=1 &>/dev/null
#打开转发
#######################################################################
sysctl -w net.ipv4.tcp_syncookies=1 &>/dev/null
#打开 syncookie (轻量级预防 DOS 攻击)
sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=3800 &>/dev/null
#设置默认 TCP 连接痴呆时长为 3800 秒(此选项可以大大降低连接数)
sysctl -w net.ipv4.ip_conntrack_max=300000 &>/dev/null
#设置支持最大连接树为 30W(这个根据你的内存和 iptables 版本来,每个 connection 需要 300 多个字节)
#######################################################################
iptables -I INPUT -s 192.168.0.50 -j ACCEPT
iptables -I FORWARD -s 192.168.0.50 -j ACCEPT
#192.168.0.50是我的机子,全部放行!

原文:

http://www.ha97.com/4096.html

svn通过钩子获取提交的文件列表

没有评论

2013 年 04 月 18 日 at 下午 10:15分类:Linux

由于之前做过通过svn的钩子去自动部署项目,这个主要是通过svn up命令来操作 把这个操作命令写在post-commit钩子文件中来达到目的;
但是这样子的过程太过于自动,不能认为的参与,即我提交到了svn版本库那么就自动同步到了web服务器,我现在有个需求就是要捕获所有开发
人员的提交的修改文件的列表 ,然后交由其他控制终端来实现是否要同步到web服务器,这种情况更加适合于同步到测试服务器的情况。由于之间写过
svn的必须写提交信息才能提交成功的钩子,那么这回马上想到了用svnlook命令来处理,但是用什么子命令呢?把svnlook的所有(也不多啦)子命令
看了一遍,觉得可以使用svnlook youngest 和svnlook changed两个命令结合来使用
其实可以不用svnlook youngest的 因为svnlook changed默认的就是当前最新的版本;
直接上代码:


REPOS="$1"
TXN="$2"

SVNLOOK=/usr/bin/svnlook

NEW_VER=`$SVNLOOK youngest $REPOS`

$SVNLOOK changed  -r $NEW_VER $REPOS > /home/list.txt

linux下tomcat的安装

没有评论

2013 年 01 月 15 日 at 下午 3:45分类:Linux

(1)安装apr,这是 Apache 为了提升 Tomcat 的性能搞的一套本地化 Socket, Thread, IO 组件也就是说它有高级 IO 功能, 操作系统级别的功能调用, 以及本地进程处理等等。
(2)安装Tomcat Native,这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。
一、安装apr
(1)安装apr

# wget http://archive.apache.org/dist/apr/apr-1.4.6.tar.gz
# tar zxvf apr-1.4.5.tar.gz 
# cd apr-1.4.5
# ./configure --prefix=/usr/local/apr
# make
# make install

(2)安装apr-iconv

# wget http://archive.apache.org/dist/apr/apr-iconv-1.2.1.tar.gz
# tar -zxvf apr-iconv-1.2.1.tar.gz
# cd apr-iconv-1.2.1
# ./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr 
# make
# make install

(3)安装apr-util

# wget http://archive.apache.org/dist/apr/apr-util-1.3.10.tar.gz
# tar zxvf apr-util-1.3.10.tar.gz
# cd apr-util-1.3.10
# ./configure --prefix=/usr/local/apr-util  --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv 
# make
# make install

二、安装tomcat和tomcat-native

(1)JDK安装

# wget http://download.oracle.com/otn-pub/java/jdk/6u25-b06/jdk-6u25-linux-x64-rpm.bin
# chmod a+x jdk-6u25-linux-x64-rpm.bin
# ./jdk-6u25-linux-x64-rpm.bin
# ln -s /usr/java/jdk1.6.0_25 /usr/local/java

设置环境变量

# vi /etc/profile

末尾增加如下内容

set JAVA_HOME=/usr/local/java
export JAVA_HOME
set PATH=$JAVA_HOME/bin:$PATH
export PATH
set CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export CLASSPATH

# java -version

查看java版本,如果是1.6的,就是说明安装成功了。

(2)安装Tomcat

# wget http://mirror.bjtu.edu.cn/apache/tomcat/tomcat-7/v7.0.16/bin/apache-tomcat-7.0.16.tar.gz
# tar -zxvf apache-tomcat-7.0.14.tar.gz
# mv apache-tomcat-7.0.14 /usr/local/www/tomcat
# vi /usr/local/www/tomcat/bin/catalina.sh

加入一行:

JAVA_HOME=/usr/local/java

(3)安装tomcat-native
安装好tomcat7之后,tomcat-native已经在tomcat的bin目录下了,可以直接使用

# cd /usr/local/www/tomcat/bin   
# tar zxvf tomcat-native.tar.gz 
# cd tomcat-native-1.1.20-src/jni/native   
# ./configure --with-apr=/usr/local/apr --with-java-home=/usr/local/java 
# make  
# make install  

(4)设置 apr 的环境变量:

# vi /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib   
# source /etc/profile  这句是为了让设置生效

启动tomcat:

# /usr/local/www/tomcat/bin/startup.sh

控制台的内容会写在logs/catalina.out中,如果只是查看的话用more logs/catalina.out就行了,效率比vi要高,按空格键可翻页。
如果想要一直查看控制台的输入内容的话,可以使用
# tail -f logs/catalina.out
终止按crul+c
以上所有路径和结果均为本地机器测试正常!

PHP安装fastDFS扩展

没有评论

2012 年 12 月 12 日 at 下午 9:20分类:Linux | PHP

1、下载FastDFS源程序,最好与FastDFS服务器版本匹配,这里我下载了FastDFS_v4.03.tar.gz版本,放在/usr/local/src目录下。
2、服务器的LNMP环境以及OK了,PHP安装目录为/usr/local/php
3、步骤

# tar zxvf FastDFS_v4.03.tar.gz
# cd FastDFS
# ./make.sh
# ./make.sh install
# cd client
# make
# make install
# cd ../php_client

如以上不安装,直接进php_client目录进行编译安装,会报如下错误:
make: *** [fastdfs_client.lo] Error 1

# /usr/local/php/bin/phpize //执行php的安装目录下的phpize
# ./configure --with-php-config=/usr/local/php/bin/php-config
# make
# make install
# cp ../conf/client.conf /etc/fdfs/
# cd /etc/fdfs/
# vi client.conf,保存
tracker_server=192.168.1.136:22122 //根据环境填写IP地址及端口号

在php.ini配置文件中加载fastdfs

# cat fastdfs_client.ini >> /usr/local/php/etc/php.ini

4、重启web服务器即可。在php_client已经有扩展函数说明和程序示例
5、验证扩展
执行命令:

# php -m | grep fastdfs

看下有木有。

Linux中awk命令的一般使用

没有评论

2012 年 12 月 02 日 at 下午 3:35分类:Linux

awk是一个非常棒的数字处理工具。相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分为数个“字段”来处理。运行效率高,而且代码简单,对格式化的文本处理能力超强。
先来看一个例子:
文件test,统计文件test的第一列中是浮点数的行的浮点数的平均值,用awk来实现只需要一句话就可以搞定
test内容:

$ cat a
1.021 33
1#.ll 44
2.53 6
6.@98 43
ss    7

awk命令如下:

awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' test
#或者:
#awk 'BEGIN{total = 0;len = 0} $1~/^[0-9]+\.[0-9]*/ {total += $1; len++} END{print total/len}' test

分析:$1~/^[0-9]+\.[0-9]*/表示$1与“/ /”里面的正则表达式进行匹配,若匹配,则total加上$1,且len自增,即数目加1.“^[0-9]+\.[0-9]*”是个正则表达式,“^[0-9]”表示以数字开头,“\.”是转义的意思,表示“.”为小数点的意思。“[0-9]*”表示0个或多个数字

awk的一般语法格式为:
  awk [-参数 变量] ‘BEGIN{初始化}条件类型1{动作1}条件类型2{动作2}。。。。END{后处理}’
其中:BEGIN和END中的语句分别在开始读取文件(in_file)之前和读取完文件之后发挥作用,可以理解为初始化和析构。

(1)参数说明:
-F re:允许awk更改其字段分隔符
-v var=$v 把v值赋值给var,如果有多个变量要赋值,那么就写多个-v,每个变量赋值对应一个-v
    e.g. 要打印文件test的第num行到num+num1行之间的行,
      awk -v num=$num -v num1=$num1 ‘NR==num,NR==num+num1{print}’ test
-f progfile:允许awk调用并执行progfile程序文件,当然progfile必须是一个符合awk语法的程序文件。

(2)awk内置变量:
ARGC: 命令行参数的个数

      awk '{print ARGC}' /etc/passwd
     

ARGV: 命令行参数数组

      awk '{print ARGV[1], ARGV[0], ARGV[1]}' /etc/passwd
     

ARGIND: 当前被处理文件的ARGV标志符

     awk '{if(ARGIND==1){print "处理test1文件"} if(ARGIND==2){print "处理test2文件"}}' test1 test2
     

文件处理的顺序是先扫描完test1文件,再扫描test2文件
NR:   已经读出的记录数
FNR: 当前文件的记录数上面的例子也可以写成这样:

     awk 'NR==FNR{print "处理文件test1"} NR > FNR{print "处理文件test2"}' test1 test2
     

输入文件test1和test2,由于先扫描test1,所以扫描test1的时候必然有NR==FNR,然后扫描b的时候,FNR从1开始计数,而NR则接着test1的行数继续计数,所以NR > FNR
e.g 要显示文件的第10行至第15行

      awk 'NR==10,NR==15{print}' kk.sh
     

FS: 输入字段分隔符(缺省为:space:),相当于-F选项

      awk -F ':' '{print}' test1    和   awk 'BEGIN{FS=":"}{print}' test1 是一样的
     

OFS: 输出字段分隔符(缺省为:space:)

     awk -F ':' 'BEGIN{OFS=";"}{print $1,$2,$3}' test2
     

如果cat test2为
1:2:3:4:5:6
那么把OFS设置成”;”后就会输出
1;2;3;4;5;6
(小注释:awk把分割后的第1、2、3个字段用$1,$2,$3…表示,$0表示整个记录(一般就是一整行))
NF: 当前记录中的字段个数

    awk -F ':' '{print NF}' test1的输出为
    3
    3
    

表明test1的每一行用分隔符”:”分割后都3个字段
可以用NF来控制输出符合要求的字段数的行,这样可以处理掉一些异常的行

    awk -F ':' '{if (NF == 3)print}' test1

RS: 输入记录分隔符,缺省为”\n”
缺省情况下,awk把一行看作一个记录;如果设置了RS,那么awk按照RS来分割记录
例如,如果文件test3,cat test3为

   hello world; I want to go swimming tomorrow;hiahia

运行

awk 'BEGIN{ RS = ";" } {print}' test3 

的结果为

    hello world
    I want to go swimming tomorrow
    hiahia

合理的使用RS和FS可以使得awk处理更多模式的文档,例如可以一次处理多行,例如文档test4, cat test4的输出为

    1 2
    3 4 5
    
    6 7
    8 9 10
    11 12

    hello

每个记录使用空行分割,每个字段使用换行符分割,这样的awk也很好写

    awk 'BEGIN{ FS = "\n"; RS = ""} {print NF}' test4 输出
    2
    3
    1

ORS:输出记录分隔符,缺省为换行符,控制每个print语句后的输出符号

awk 'BEGIN{ FS = "\n"; RS = ""; ORS = ";"} {print NF}' test4 输出[code]
   2;3;1

(3)awk读取shell中的变量
可以使用-v选项实现功能
$b=1
$cat test5
apple

$ awk -v var=$b '{print var, $var}' test5
1 apple

其实上面的$var已经被解析成了$1了,于是出来的结果是apple.
至于有没有办法把awk中的变量传给shell呢,这个问题我是这样理解的。shell调用awk实际上是fork一个子进程出来,而子进程是无法向父进程传递变量的,除非用重定向(包括管道)

$ a=$(awk '{print $b, '$b'}' test5)
$ echo $a
apple 1

(4)输出重定向
awk的输出重定向类似于shell的重定向。重定向的目标文件名必须用双引号引用起来。

$awk '$4 >=70 {print $1,$2 > "destfile" }' filename
$awk '$4 >=70 {print $1,$2 >> "destfile" }' filename

(5)awk中调用shell命令:

awk中的管道概念和shell的管道类似,都是使用"|"符号。如果在awk程序中打开了管道,必须先关闭该管道才能打开另一个管道。也就是说一次只能打开一个管道。shell命令必须被双引号引用起来。“如果打算再次在awk程序中使用某个文件或管道进行读写,则可能要先关闭程序,因为其中的管道会保持打开状态直至脚本运行结束。注意,管道一旦被打开,就会保持打开状态直至awk退出。因此END块中的语句也会收到管道的影响。(可以在END的第一行关闭管道)”
awk中使用管道有两种语法,分别是:

awk output | shell input
shell output | awk input

对于awk output | shell input来说,shell接收awk的输出,并进行处理。需要注意的是,awk的output是先缓存在pipe中,等输出完毕后再调用shell命令 处理,shell命令只处理一次,而且处理的时机是“awk程序结束时,或者管道关闭时(需要显式的关闭管道)”

$awk '/west/{count++} {printf "%s %s\t\t%-15s\n", $3,$4,$1 | "sort +1"} END{close "sort +1"; printf "The number of sales pers in the western"; printf "region is " count "." }' datafile 

解释:/west/{count++}表示与“wes”t进行匹配,若匹配,则count自增
printf函数用于将输出格式化并发送给管道。所有输出集齐后,被一同发送给sort命令。必须用与打开时完全相同的命令来关闭管道(sort +1),否则END块中的语句将与前面的输出一起被排序。此处的sort命令只执行一次。

在shell output | awk input中awk的input只能是getline函数。shell执行的结果缓存于pipe中,再传送给awk处理,如果有多行数据,awk的getline命令可能调用多次。

$ awk 'BEGIN{ while(("ls" | getline d) > 0) print d}' test5