05 29

消息队列RabbitMQ(一):介绍

什么是RabbitMQ?

AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

基本特性

1)可靠性
消息持久化、消息发送和投递确认机制、集群高可用方案

2)灵活路由
消息通过exchange的方式路由到不同的queue中,提供了包括fanout, direct, topic等多种exchange实现,并且支持通过编写exchange插件的方式自实现路由方案

3)支持集群
同网段下的rabbitmq节点可以通过集群的方式,组成一个逻辑上的单一broker

4)Federation
通过Federation可以在跨网段节点间组件集群

5)高可用消息队列
通过设置镜像队列的方式,消息可以在镜像队列间进行复制,使节点down机或硬件损坏的情况下保证队列服务的高可用

6)多协议支持
包括AMQP, STOMP, MQTT, HTTP等多种消息交换协议

7)多客户端支持
JAVA, .NET, Ruby, Python, PHP, Node, Go……

8)可视化管理界面
RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。

9)丰富的插件支持
tracing, managment-plugin, and you can also write your own.

RabbitMQ中的重要概念

Virtual Host

虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。

Broker

经纪人。提供一种传输服务,维护一条从生产者到消费者的传输线路,保证消息数据能按照指定的方式传输。粗略的可以将图中的RabbitMQ Server当作Broker。

Producer

消息生产者。主要将消息投递到对应的Exchange上面。一般是独立的程序。

Consumer

消息消费者。消息的接收者,一般是独立的程序。

Message

消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

Channel

信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。

对于操作系统来说,建立和关闭TCP连接是有代价的,频繁的建立关闭TCP连接对于系统的性能有很大的影响,而且TCP的连接数也有限制,这也限制了系统处理高并发的能力。但是,在TCP连接中建立Channel是没有上述代价的。对于Producer或者Consumer来说,可以并发的使用多个Channel进行Publish或者Receive。

Exchange

消息交换机。指定消息按照什么规则路由到哪个队列Queue。

Producer将并不能直接将消息投递到Queue中。需要将消息发送到Exchange,由Exchange将消息路由到一个或多个Queue中(或者没有绑定Queue的情况下将消息丢弃)。

Exchange是按照什么逻辑将消息路由到Queue的?这个将在下面Binding中介绍。 RabbitMQ中的Exchange有四种类型,不同的类型有着不同的路由策略,这将在下面Exchange类型中介绍。

Queue

消息队列。消息的载体,每条消息都会被投送到一个或多个队列中。

RabbitMQ中的消息都只能存储在Queue中,Producer生产消息并通过Exchange投递到Queue中,Consumer可以通过Exchange从Queue中获取消息并消费。

多个消费者可以订阅同一个Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。

Binding

绑定。作用就是将Exchange和Queue按照某种路由规则绑定起来。这样RabbitMQ就知道如何正确地将消息路由到指定的Queue了。

08 03

Linux服务器上查杀木马经历

收到VPS服务商的邮件,警告说我的VPS服务器的负载过高,已经被暂时关闭了,让我赶快处理解决。

Suspend Reason: High Load Avg - 23.13 / 23.17 / 23.16

很是诧异,这个VPS就放了一个博客和两个小站点,平时也没啥访问,怎么会导致负载高呢。

解决过程

急忙登陆上了vps,发现连接特别慢,马上top查看下,输入P进行按照CPU排序。

多了个CPU占用特别高的陌生程序minerd,明显是被挂马了,网上搜索了下,发现这个是个挖矿程序,被攻击了。

使用kill -9 pid 明显杀掉进程,但是马上又自动运行了,应该有其他守护程序还在运行。

再次ps -aux 查看了下进程,没有发现什么异常的进程,我的进程数不多,开启的服务也比较少,比较集中的程序是在/etc/inti.d/ 目录,进去使用ll -a查看了下,发现ntp服务在前两天被修改过,和minerd的时间刚好匹配上。

马上kill掉这个程序,在kill minerd,发现终于恢复正常了。

04 26

WEB/APP开发安全

最近公司被攻击了,然后才发现公司代码简直一点安全防范意识都没有,连基本的SQL,XSS过滤都没有,发现大部分PHP程序员都缺乏安全相关的了解。下面就我们遇到的一些攻击进行科普以及防范方案。

SQL注入

SQL注入是WEB攻击中最常见的注入方式。也是我们这次被攻击中最多的。
由于我们的程序中大部分都是进行拼装SQL的方式,然后对于用户输入的参数也没有进行过滤,导致给攻击者留下了漏洞。
具体为,登录的操作,一般是通过POST方式将username和password传递过来。

SELECT * FROM user WHERE username='$username' AND password='$password'

正常情况下,我们希望执行的SQL是

SELECT * FROM user WHERE username='vckai' AND password='123456'

但是如果攻击者传递的用户为非法用户名vckai' or 1=1--,在SQL里面—是注释标记,所以查询语句会在此中断。这就让攻击者在不知道任何合法用户名和密码的情况下成功登录了。

SELECT * FROM user WHERE username='vckai' or 1=1--' AND password='123456'

甚至于,攻击者可以用同样的方式执行其他SQL,查询出你其他DB和表数据。

现在知道SQL注入的危害了,那怎么预防呢?

  • 首先在PHP中,首先对于int类型的数据,一定要在接收数据的时候进行(int) $_POST['pagesize']进行强转义。
  • 根据业务做参数验证,如用户名一般只允许4-20位字符和数字。这样攻击者就没办法根据这个进行注入了。
  • 虽然MySQL和PHP本身由提供过滤函数addslashesmysql_real_escape_string进行转义,但是仍然有被绕过的风险,所以最佳方法是使用PDO的预处理。

XSS攻击

XSS通常可以分为两大类:一类是存储型XSS,主要出现在让用户输入数据,供其他浏览此页的用户进行查看的地方,包括留言、评论、博客日志和各类表单等。应用程序从数据库中查询数据,在页面中显示出来,攻击者在相关页面输入恶意的脚本数据后,用户浏览此类页面时就可能受到攻击。这个流程简单可以描述为:恶意用户的Html输入Web程序->进入数据库->Web程序->用户浏览器。另一类是反射型XSS,主要做法是将脚本代码加入URL地址的请求参数里,请求参数进入程序后在页面直接输出,用户点击类似的恶意链接就可能受到攻击。

XSS目前主要的手段和目的如下:

  • 盗用cookie,获取敏感信息。
  • 利用植入Flash,通过crossdomain权限设置进一步获取更高权限;或者利用Java等得到类似的操作。
  • 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击者)用户的身份执行一些管理动作,或执行一些如:发微博、加好友、发私信等常规操作,前段时间新浪微博就遭遇过一次XSS。
  • 利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。
  • 在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDoS攻击的效果

如何预防XSS攻击
答案很简单,坚决不要相信用户的任何输入,并过滤掉输入中的所有特殊字符。这样就能消灭绝大部分的XSS攻击。

  • 使用htmlspecialchars函数进行参数过滤,将<>转换为HTML实体。注意,有一些APP开发的时候,会直接输出HTML实体,导致用户正常数据处理错误,所以返回给APP的时候,建议再转义回来htmlspecialchars_decode,或者让客户端做统一处理。
03 30

使用GDB调试PHP core dump

最近线上服务器出现了访问不上的情况,查看php-fpm发现大量的WARNING: [pool www] child 11274 exited on signal 31 (SIGSYS) after 0.089068 seconds from start错误,然后php-fpm进程在不断的重启。

查看PHP的错误日记并没有太多可用信息,既然如此那就尝试抓取core dump使用gdb调试看下吧。

关于core dump

我们经常听到大家说到程序core掉了,需要定位解决,这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止,并且在满足一定条件下(这里为什么说需要满足一定的条件呢?下面会分析)会产生一个叫做core的文件。

通常情况下,core文件会包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,我们可以理解为是程序工作当前状态存储生成第一个文件,许多的程序出错的时候都会产生一个core文件,通过工具分析这个文件,我们可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题所在并进行及时解决。

core dump默认是不生成的文件,所以首先我们要开启下。

设置core dump路径

# echo "/tmp/core.%p" > /proc/sys/kernel/core_pattern

修改ulimit允许生成core dump文件

# ulimit -c unlimited

重启php-fpm。 过一会进入/tmp,就会发现生成很多core.xxx的文件。这个时候设置关闭core dump并重启php-fpm。

# ulimit -c 0

这个时候就可以使用gdb进行调试core dump,注意因为生成core dump的是php-fpm,所以这里需要使用php-fpm进行调试。如果在cli模式使用php生成的core dump才是使用php程序进行调试。

01 06

centos6 下安装nginx1.7.9+php5.6.4+mysql5.6.2

该文章是由于我在docker安装LNMP环境时出现的,原型是张宴大哥这篇文章:http://zyan.cc/nginx_php_v7/ ,只是做了一些软件升级变更。

安装关联库

# mkdir -p /data/tgz
# cd /data/tgz
# yum install wget
# yum install pcre
# yum install openssl*
# yum install tar
# yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers make gd gd2 gd-devel gd2-devel

# ulimit -SHn 65535
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz
# tar zxvf pcre-8.36.tar.gz
# cd pcre-8.36
# ./configure --prefix=/data/apps/pcre
# make && make install
# cd ../
下一页