分类 Linux系统运维 下的文章

base64编码

By firefoxbug

shell base64编码


[root@firefoxbug] str="hello world"

[root@firefoxbug] echo -n "$str" | base64

aGVsbG8gd29ybGQ=

[root@firefoxbug] echo "$str" | base64 注意要加 -n ,不然会有换行,编码就有问题了。

aGVsbG8gd29ybGQK

shell base64解码


-d :decode

[root@firefoxbug]  echo -n "$str" | base64 | base64 -d

hello world

python base64编码


[code]
#!/usr/bin/python
#-*-coding:utf-8-*-

import base64
sour_str = "hello world"
print base64.encodestring(sour_str)
[/code]

python base64解码


[code]
#!/usr/bin/python
#-*-coding:utf-8-*-

import base64
sour_str = "hello world"
decode_str = base64.encodestring(sour_str)
print base64.decodestring(decode_str)
[/code]

shell字符串操作

By firefoxbug
string="abcABC123ABCabc"
字符串长度:

echo ${#string}			#15
echo `expr length $string`	#15

索引


用法:expr index $string $substring

expr index $string "ABC"	#4

提取子串


用法:${string:position}

echo ${string:3}		#ABC123ABCabc

提取指定长度子串
用法:${string:position:length}

echo ${string:3:3}		#ABC

从末尾提取子串
用法:
${string: -length}注意有空格
${string:(-length)}

echo ${string:(-3)}		#abc

子串剔除

从左边开始截吊第一个匹配的$substring
用法:${string#*substring}

echo ${string#*abc}		#ABC123ABCabc
substr="abc";echo ${string#*$substr}	##ABC123ABCabc

从左边开始截吊最后一个匹配的$substring
[php]
echo ${string##*abc} #
[/php]

从右边开始截吊第一个匹配的$substring
用法:${string%substring*}

echo ${string%abc*}		#abcABC123ABC

从右边开始截吊最后一个匹配的$substring

echo ${string%%abc*}		#

子串替换


用$replacement来替换第一个匹配的$substring
用法:${string/substring/replacement}

echo ${string/ABC/XYZ}		#abcXYZ123ABCabc

用$replacement来替换全部匹配的$substring
用法:${string//substring/replacement}

echo ${string//ABC/XYZ}		#abcXYZ123XYZabc

如果$substring匹配$string的开头部分,那么就用$replacement来替换
用法:${string/#substring/replacement}

echo ${string/#abc/xyz}		#xyzABC123ABCabc

如果$substring匹配$string的结尾部分,那么就用$replacement来替换
用法:${string/%substring/replacement}

echo ${string/%abc/xyz}		#abcABC123ABCxyz

自建CDN防御DDoS(1):知己知彼,建设持久防线

from http://www.infoq.com/cn/articles/anti-ddos-cdn-1


背景介绍


客服系统的主要业务是提供基于网页的实时动态的文字聊天,主要应用在各类网络商品销售、网站在线客服等领域,总用户数58万,同时在线活跃的用户约12万/天。

这些应用领域通常行业之间的竞争比较激烈,其中包括在线下无法名正言顺的灰色+暴利产业,导致竞争对手之间经常发动DDoS恶意攻击。但营销网站往往是单面加速,加上推广时效性很强,很难被彻底打击,于是一些自作聪明的黑客通过攻击网站的在线客服系统,导致网站无法跟访客沟通,不能交易,从而达到恶意攻击的目的。因此客服系统这个原本有助于网站营销的工具反而成了被攻击的主要对象,虽然伤得委屈,但也不得不面对挑战。

我们遭遇的DDoS攻击类型包括:延缓性的CC攻击和致命的大流量攻击。下面将对两种攻击方式的攻击特点、防御思路和我们用过的一些防御方案进行简单的介绍。

- 阅读剩余部分 -

ganglia

之前和杰哥聊天过程中发现了ganglia这个开源的项目,发现还是比较给力的.

快速开始向导


介绍


Ganglia 监控套件包括三个主要部分:gmond,gmetad,和网页接口,通常被称为ganlia-web

gmond 是一个守护进程,他运行在每一个需要监测的节点上,收集监测统计,发送和接受在同一个组播或单播通道上的统计信息
*如果他是一个发送者(mute=no)他会收集基本指标,比如系统负载(load_one),CPU利用率。他同时也会发送用户通过添加C/Python模块来自定义的指标。
*如果他是一个接收者(deaf=no)他会聚合所有从别的主机上发来的指标,并把它们都保存在内存缓冲区中。
gmetad 也是一个守护进程,他定期检查gmonds,从那里拉取数据,并将他们的指标存储在RRD存储引擎中。他可以查询多个集群并聚合指标。他也被用于生成用户界面的web前端。
ganglia-web 顾名思义,他应该安装在有gmetad运行的机器上,以便读取RRD文件。

集群是主机和度量数据的逻辑分组,比如数据库服务器,网页服务器,生产,测试,QA等,他们都是完全分开的,你需要为每个集群运行单独的gmond实例。
一般来说每个集群需要一个接收的gmond,每个网站需要一个gmetad。

- 阅读剩余部分 -

奇偶校验

信息是以比特流的方式传输的,类似01000001。在传输过程中,有可能会发生错误,比如,我们存储了

01000001,但是取出来却是01000000,即低位由0变成了1。为了检测到这种错误,我们可以通过“奇偶

校验”来实现。假如,我们存储的数据是一个字节,8个比特位,那我们就可以计算每个字节比特位是1的

个数,如果是偶数个1,那么,我们就把第九个位设为1,如果是奇数个1,那么就把第九个位设为0,这

样连续9个字节比特位为1的位数肯定是奇数。这中方法叫做“奇校验”,“偶校验”和此类似。当然,在实

际应用中,也可以把一个字节的前7位作为数据位,最后一个为作为校验位。

CRC 校验的基本过程

采用 CRC 校验时,发送方和接收方用同一个生成多项式 g(x) , g(x) 是一个 GF(2) 多项式,并且 g(x) 的首位和最后一位的系数必须为 1 。

CRC 的处理方法是:发送方用发送数据的二进制多项式 t(x) 除以 g(x) ,得到余数 y(x) 作为 CRC 校验码。校验时,以计算的校正结果是否为 0 为据,判断数据帧是否出错。设生成多项式是 r 阶的(最高位是 x^r )具体步骤如下面的描述。

发送方:

1 )在发送的 m 位数据的二进制多项式 t(x) 后添加 r 个 0 ,扩张到 m+ r 位,以容纳 r 位的校验码,追加 0 后的二进制多项式为  T(x) ;

2 )用 T(x) 除以生成多项式 g(x) ,得到 r 位的余数 y(x) ,它就是 CRC 校验码;

3 )把 y(x) 追加到 t(x) 后面,此时的数据 s(x) 就是包含了 CRC 校验码的待发送字符串;由于 s(x) = t(x) y(x) ,因此 s(x) 肯定能被 g(x) 除尽。

接收方:

1 )接收数据 n(x) ,这个 n(x) 就是包含了 CRC 校验码的 m+r 位数据;

2 )计算 n(x) 除以 g(x) ,如果余数为 0 则表示传输过程没有错误,否则表示有错误。从 n(x) 去掉尾部的 r 位数据,得到的就是原始数据。

nginx与squid 反向代理的区别

反向代理从传输上可以区分为同步模式和异步模式,apache的mod_proxy和squid都属于同步模式,nginx和lighttpd属于异步模式

同步模式是用户发起请求,请求立即被转到后端的服务器,于是在浏览器和后端服务器之间就建立了一个连接,在请求完成前这个连接是一直存在的。

而异步模式时,用户发起的请求会发送到nginx,nginx接收到所有的数据后在转发到后端的服务器,后端服务器处理完成后把数据返回给nginx,nginx在返回给用户。

由此可见如果用户发起的请求的数据比较大,或者用户端的网速比较慢,同步模式时后端服务器的连接数相对于异步模式会比较多,压力也比较大。

Nginx的cache比较适合处理大文件的,而squid的cache比较适合小文件的cache

SaltStack安装

之前尝试了下puppet,感觉还是比较重,比较繁琐。早上试了下SaltStack,python写的就是兼容性好,安装 起来也方便,试用了一些,还是挺方便的,就是不知道承载能力怎么样。下面是安装教程

salt-master安装

[salt-master]# yum install salt-master

master端的配置文件是在 /etc/salt/master 对于此配置文件的详细配置可以查看  http://docs.saltstack.org/en/latest/ref/configuration/master.html 运行:

- 阅读剩余部分 -

puppet安装和使用

puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置

文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标

是简化对这些资源的管理以及妥善处理资源间的依赖关系。

puppet采用C/S星状的结构,所有的客户端和一个或几个服务器交互。每个客户端周期的(默认半个小时)

向服务器发送请求,获得其最新的配置信息,保证和该配置信息同步。每个puppet客户端每半小时(可以设

置)连接一次服务器端, 下载最新的配置文件,并且严格按照配置文件来配置服务器. 配置完成以后,puppet客

户端可以反馈给服务器端一个消息. 如果出错,也会给服务器端反馈一个消息.

puppet通信过程中,客户端向服务端请求时端口是8140,若是服务器推送到客户端时通信端口是8319,

所以安装和通信过程要注意防火墙的配置!!!可以先关闭.

更新puppet源


rpm -ivh "http://yum.puppetlabs.com/el/5/products/i386/puppetlabs-release-5-1.noarch.rpm"
rpm -ivh "http://yum.puppetlabs.com/el/5/products/x86_64/puppetlabs-release-5-1.noarch.rpm"
rpm -ivh "http://yum.puppetlabs.com/el/6/products/i386/puppetlabs-release-6-1.noarch.rpm"
rpm -ivh "http://yum.puppetlabs.com/el/5/products/x86_64/puppetlabs-release-5-1.noarch.rpm"

puppet服务端安装


# puppet server install ==>> 主机名 : puppet_server IP : 1.1.1.1

yum -y install ruby ruby-lib ruby-rdoc
yum -y install puppet-server
chkconfig puppet on
service puppetmaster start
/etc/init.d/iptables stop > /dev/null 2>&1

puppet客户端安装


# puppet client install  ==>> 主机名 : puppet_clientIP : 1.1.1.2

echo "1.1.1.1 puppet_server" >> /etc/hosts  (服务端主机名)
yum -y install ruby ruby-lib ruby-rdoc
yum -y install puppet

puppet客户端发送证书


#客户端第一次启动向服务端发送证书,要求签好之后才能通信
puppet agent --no-daemonize --onetime --verbose --debug --server=puppet_server(服务端主机名)

puppet服务端签证书


puppet cert list --all #查看所有客户端的请求(有+号的代表已经签好证书可以通信,没有加号的代表尚未签好证书)
puppet cert --sign puppet_client(客户端主机名) #这条命令加客户端主机名就能签字,自此可以通信

1.下面是一个文件同步的例子


puppet服务端
# vim /etc/puppet/fileserver.conf

# This file consists of arbitrarily named sections/modules
# defining where files are served from and to whom

# Define a section 'files'
# Adapt the allow/deny settings to your needs. Order
# for allow/deny does not matter, allow always takes precedence
# over deny
# [files]
#  path /var/lib/puppet/files
#  allow *.example.com
#  deny *.evil.example.com
#  allow 192.168.0.0/24

# 在下面加一个配置域,名字叫做opencdn,路径是 /etc/puppet
opencdn
  path /etc/puppet
  allow *

# vim /etc/puppet/manifests/site.pp

node default {
        file {
                "/tmp/helloworld.txt" :				==>>推送到客户端的路径文件
                source=>"puppet:///opencdn/test1/helloworld.txt", ==>> 根据/etc/puppet/fileserver.conf里面配置的opecnd域
               							#最终路径是/etc/puppet/test1/helloworld.txt
		recurse=>"true",				==>>可以传送目录
                owner=>"root",
                group=>"root",
                mode=>777,
        }
}

# mkdir /etc/puppet/test1/
# cat /etc/puppet/test1/helloworld.txt
到这里为止puppet的服务端已经设置好了

puppet客户端

# puppet agent --test --server=puppet_server(服务端主机名)
# cat /tmp/helloworld.txt 就OK了

2.puppet从服务端推送系统命令到客户端执行


# vim /etc/puppet/manifests/site.pp

node default {
	exec { "/bin/ls > 1.txt": ==>> 这里对于""里面的字符要求很高,/bin/ls之前都不能有空格,否则就会提示错误
		cwd => "/tmp",	==>> 客户端执行命令的路径
		path=> "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin", ==>> 对于命令的系统路径
	}
}

3.一次推送多个指令


node default {
        exec { "service opencdn restart":
                cwd => "/tmp",
                path=> "/usr/bin:/usr/sbin:/bin:/sbin",
        }
        exec { "ls > 1.txt":
                cwd => "/tmp",
                path=> "/usr/bin:/usr/sbin:/bin:/sbin",
        }
	file {
		"/tmp/helloworld.txt" :
		source=>"puppet:///opencdn/test1/helloworld.txt",
		owner=>"root",
		group=>"root",
		mode=>777,
	}
}

puppet推送到客户端

iptables


puppet客户端

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 8319 -j ACCEPT

puppet服务端

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 8140 -j ACCEPT

puppet服务端推送 puppet 指令或者文件到客户端的时候可以用 kick 实现

puppet kick -d --hostpuppet_client

但是会出现 error

puppet failed: Connection refused - connect(2)

解决:

puppet客户端


# vim /ect/puppet/puppet.conf ==>> 客户端加入监听

[agent]
listen = true

# vim /ect/puppet/auth.conf

# this one is not stricly necessary, but it has the merit
# to show the default policy which is deny everything else
path /
auth any
allow *

重启 puppet 服务

service puppet restart

puppet服务端


/etc/puppet/namespaceauth.conf

[puppetrunner]
allow *

详情查看

不过按照以上配置好之后,还是会有一些bug,我也不明白是什么原因.

我在服务端设置 site.pp

node default {
        exec { "service opencdn stop":
                cwd => "/tmp",
                path=> "/usr/bin:/usr/sbin:/bin:/sbin",
        }
        exec { "ls > 1.txt":
                cwd => "/tmp",
                path=> "/usr/bin:/usr/sbin:/bin:/sbin",
        }
        file {
                "/tmp/helloworld.txt" :
                source=>"puppet:///opencdn/test1/helloworld.txt",
                owner=>"root",
                group=>"root",
                mode=>777,
        }
}

然后在服务端执行puppet kick -d --hostpuppet_client这个命令的时候,在客户端实际上

只执行了一条命令,其他的几条语句都没有执行.

解决方案


在puppet客户端

# vim /etc/sysconfig/puppet

# The puppetmaster server
PUPPET_SERVER=puppet_server

OpenCDN安装说明


OpenCDN管控中心安装


# wget http://ocdn.me/wp-content/down/ocdn_console_last.tar.gz
# tar -zxvf ocdn_console_last.tar.gz
# cd ocdn_console 
# ./install.sh

1

2

3

4

OpenCDN节点端安装


# wget http://ocdn.me/wp-content/down/ocdn_node_last.tar.gz
# tar -zxvf ocdn_node_last.tar.gz
# cd ocdn_node
# ./install.sh

1

2

OpenCDN管控中心卸载


5

OpenCDN节点端卸载


3

Linux注册系统服务

注册一个系统服务,开机自启动.

1 脚本编写


#vim test.sh

#!/bin/bash

#description: hello.sh
#chkconfig: 2345 20 81

EXEC_PATH=/usr/local/
EXEC=hello.sh
DAEMON=/usr/local/hello.sh
PID_FILE=/var/run/hello.sh.pid

. /etc/rc.d/init.d/functions

if [ ! -x $EXEC_PATH/$EXEC ] ; then
       echo "ERROR: $DAEMON not found"
       exit 1
fi

stop()
{
       echo "Stoping $EXEC ..."
       ps aux | grep "$DAEMON" | kill -9 `awk '{print $2}'` >/dev/null 2>&1
       rm -f $PID_FILE
       usleep 100
       echo "Shutting down $EXEC: [  OK  ]"
}

start()
{
       echo "Starting $EXEC ..."
       $DAEMON > /dev/null &
       pidof $EXEC > $PID_FILE
       usleep 100
       echo "Starting $EXEC: [  OK  ]"
}

restart()
{
	stop
	start
}

case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	restart)
		restart
		;;
	status)
		status -p $PID_FILE $DAEMON
		;;
	*)
		echo "Usage: service $EXEC {start|stop|restart|status}"
		exit 1
esac

exit $?

2注册服务

- 阅读剩余部分 -

mysql-bin0000xx处理

今天一看vps磁盘空间暴涨,然后用 du --max-depth=1 -h 从根目录一级一级往下查,最后发现在mysql子

目录下发现很多mysql-bin0000等文件,这应该是日志文件。通过下面的可以清除:

到 /usr/local/mysql/var 把日志清了。或者

/usr/local/mysql/bin/mysql -u root -p
mysql> reset master;

vim /etc/my.cnf

log-bin=mysql-bin
binlog_format=mixed

这两行注释了,重启mysql就OK。

 

awk小技巧

[code]
awk指定多个分隔符号
echo "hello=world=from=linux&google" | awk -F "[=&]" '{print $1,$2,$3,$4,$5}'
==>> hello world from linux google
awk以字符串作为分隔符
echo "hello=world=from=linux&google" | awk -F "from" '{print $1,$2}'
==>> hello=world= =linux&google
awk 给外部变量赋值
采用eval可以对执行的命令做两次扫描,第一次是做替换,第二次是真正执行
eval $(echo "hello=world=from=linux&google" | awk -F "[=&]" '{printf("a=%s\nb=%s\nc=%s\nd=%s\ne=%s\n",$1,$2,$3,$4,$5)}')
echo $a $b $c $d $e
==>> hello world from linux google
[/code]

inotify 安装

传统的rsync+crontab同步数据和实际会有差异,而inotify则基本可以达到实时的效果,当文件有任何变

动,就会触发inotify。

inotify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删

- 阅读剩余部分 -