虚拟专用网(VPN)之无法访问百度之谜

不久前开了个香港Sunny Vsion的VPN,平时我一般都不使用VPN,今天才发现无法访问百度,而尝试其他网站却正常,遂探讨了一番。

我使用的都是学校的中国电信网络,本地连接VPN后,访问百度网站无任何回应,在服务器上可以成功地使用curl对百度发起请求,检查了iptables,未发现任何问题。

既然服务器能访问,那么理论上VPN也有权访问,但现在却与理论背道而驰。为了找出问题的根源,搬出抓包神器——tcpdump。

首先我在服务器上抓取本地分别透过VPN访问cPanel/WHM的208.74.0.0/16与百度的103.235.46.39/32的数据包,以作对比,查找错误。

cPanel/WHM:

百度:

首先,在两边的记录,都可以看到Flags [P.],这是开始传输内容的标记,因此可以肯定,我们本地与百度之间的TCP三次握手是顺利地完成了的,不然也就不会开始传输数据。

在与cPanel/WHM服务器通讯时,看到了Flags [F.],这是完成数据传输,结束TCP连接的标记。

但是在百度却没看到Flags [F.],可以看到103.235.46.39发送了很多类似seq 1:1063的数据包,但是我们本地仅返回了ack 1063给百度,根据TCP协议,ack的可以理解为“确认收到”,ack 1063,那就是说我们本地告诉百度的服务器确认收到了seq 1:1063的数据包。

TCP是一个可靠的协议,之所以说可靠,是因为服务器会重新发送客户端没有收到的数据包,可以保障数据的完整性,既然我们本地仅返回了ack 1063,百度服务器很自然就会重发我们没收到的数据包,也就对应了百度那边的抓包结果最后面的seq 1063:2515。

总算找到方向了:我们本地可能没有完整地收到百度发送的所有数据包!

为了确定我们本地是否真的没有收到数据包,我再次访问百度,并进行了双边抓包:

本地:

服务器:

服务器完完整整地收到了百度发送的数据包,我们本地收到了seq 1:1062,但下一个seq是6870:8262,再下一个居然是18426:19782!这丢包率真把我给吓坏了……

赶紧从本地MTR到服务器看看:

MTR To Server

然后走VPN MTR到百度看看:

MTR To BAIDU via VPN

虽然MTR可以看到有少量丢包,不过这丢包率完全不符合我TCPDUMP的结果,这说明这丢包根本不是线路不佳造成的。

完全不服……

想起来之前在家研究广电机顶盒时,遇到过桥架网卡后因为其中一个网卡MTU非1500(桥接后,桥接网卡的MTU不能大于MTU最小的网卡的MTU)而导致PPPOE连接成功却打不开网页的情况。

MTU是什么不在此长篇大论,至于为什么要减掉一部分数值,是构建了虚拟隧道的问题,数据包进入虚拟隧道前,还是要封装成适合进入这个虚拟隧道的类型的,因此数据包体积会比原来大,具体细节,不在此长篇大论,各位有兴趣可以通过搜索引擎了解。

更好服务器上也用桥接网卡,于是看了下br0(桥接网卡), eth0(物理网卡)和服务器与我本地通讯的ppp1的MTU:

MTU

br0和eth0都是1500, ppp1是1496,我本地的ppp也是1496。

看起来是非常正常且毫无问题的,因为默认情况下VPN构建的ppp的MTU都是1496这个值……

不过既然是非线路问题导致的丢包,改改MTU也无妨,于是分别在服务器和本地都把VPN构建的ppp的MTU改成1400:

再次curl百度:

CURL BAIDU

是成功地连上了……

不过我之前都在未桥架的服务器上搭建VPN,为了探究清楚是桥架还是该服务器的网络环境的问题,我又在另一台使用了桥架的服务器搭建了VPN并访问百度: CURL BAIDU USA

还好是成功的,ppp的mtu同样是1496,这就说明了这个问题在这次与桥接不沾边,是这台Sunny Vision服务器的问题。

虽然最后成功解决了无法打开百度(现在应该是说比较大的网页)的问题,但最大的问题是,目前为止,对于是何导致了此服务器无法使用1496,我还没有任何思绪……

才疏学浅啊,若各位有见解,请告知一下……

QEMU -smp参数解释及在libvirt中的设置(多CPU 多核心 多线程)

最近给一台安装了Windows Server 2003标准版的虚拟服务器分配了八个虚拟处理器,在设备管理器中,可以查看到已成功识别所有处理器,但是任务管理器的性能标签页中看到仅有四个被使用,查阅了一下微软官方的文档,发现原来标准版最多只能使用四个处理器。

解决问题的方向可以明确:让QEMU从分配多CPU,单CPU核心,改为分配单或多CPU,多CPU核心。

QEMU -smp参数

QEMU与多CPU多核心有关的参数是-smp,官方对-smp参数的解释如下:

-smp n[,cores=cores][,threads=threads][,sockets=sockets][,maxcpus=maxcpus]
Simulate an SMP system with n CPUs. On the PC target, up to 255 CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs to 4. For the PC target, the number
of cores per socket, the number of threads per cores and the total number of sockets can be specified. Missing values will be computed. If any on the three values is given, the
total number of CPUs n can be omitted. maxcpus specifies the maximum number of hotpluggable CPUs.

也许你和我一样,看了这些解释,感觉和没看一样。

经过数次“实战”,稍微了解了一些,因此,我就来给你解释一下n,cores,threads,sockets, maxcpus及他们之间的关系吧。

n: 虚拟CPU(vcpu)的个数,每个thread都视为一个虚拟CPU

sockets: CPU插槽数目,也就是CPU的个数

threads: 每个CPU核心拥有的线程数目

cores: 每个CPU拥有的CPU核心数目

maxcpus: 根据文档,是设置可热插拔的CPU数量,经测试,n的值不可超过maxcpus

根据对硬件的了解,可以知道,总的cores数目=cores*sockets,总的threads数目=总的cores数目*threads

我就不扯更多理论了,举例说明吧:

实例一. -smp 1,cores=1,threads=1,sockets=1

这里指定了虚拟CPU为一,CPU个数为一,核心数为一,线程数为一,那么在虚拟机中可以看到一个CPU,核心数为一,线程数为一:

CPU

 

实例二. -smp 2,cores=1,threads=1,sockets=2

在虚拟服务器中可以看到有两个CPU,每个CPU拥有一个核心,每个核心拥有一个线程:

cpu-2-1 cpu-2-2

实例三. -smp 16,cores=2,threads=2,sockets=4

在服务器中可以看到共有四个CPU,每个CPU拥有两个核心,每个CPU核心拥有两个线程,也就是每个CPU拥有四个线程:

cpu-3-1 cpu-3-2 cpu-3-3 cpu-3-4

 

那么,我要让Windows Server 2003的虚拟服务器能使用八个vcpu,只要控制socket的值小于等于4,且大于等于1就可以了:

这样虚拟服务器里面就可以看到一个CPU,每个CPU拥有八个个核心,每个核心拥有一个线程。

在LIBVIRT中的设置方法

相信大家也用LIBVIRT管理虚拟服务器,根据LIBVIRT的官方文档,有两个是控制-smp参数的。

控制vcpu的数量,也就是-smp的n的值:

控制sockets, cores, threads的值:

要让Windows Server 2003的虚拟服务器拥有一个八核八线程的CPU,LIBVIRT的XML配置文件的相关内容应该如下:

 

『T.S. 89』两个晚来的提高大麦网购票成功率的方法

QQ在线人数统计及其分布图

大家可以看到,那个小亮点数目最多的,最亮的省,是广东省,尤其是珠三角地区!
所以在此提出一个猜测:
在大麦网购票失败的人当中,在广东省购票的人占的比例最大。

也许你会说广东省人多,那购票的人当中,广东省的人所占的比例自然就多,购票失败的广东人占购票失败的人的比例也会多,但你有没有想过为什么呢?

对于大麦网这种网站,要同时应付N多人访问,且保证速度,服务器仅有一台,或仅在一个地区,是不可能的,服务器是分布式的,才能为如此多的访客提供服务(证据:http://www.17ce.com/site/http/201507_a97522b8b50b05c4f2e18c9e579cf1ee.html)。使用分布式服务器,或者CDN,为了能让不同地区的访客均能以最快的速度访问到他们的网站,就要使用NS服务器智能地根据访客的IP给访客返回不同的IP地址(一般是离访客最近的,且ISP相同的)。
由于广东省人多,那同时使用分配给了广东省的服务器的人就多,人多了,服务器就不堪重负,出现拒绝服务的情况,访问人数相对较少的服务器,服务器相对比较空闲,可能仍然有余力处理大量订单。
当然这只是他们的一部分服务器,他们处理订票数据的服务器具体如何部署我不太清楚,但不排除也是分布式的。

所以,下次想提高购票的成功率,访问一个访问人数相对较少的服务器是关键。
想知道哪里人数少,可以使用QQ的在线图作为参考:http://im.qq.com/,点击右上角的“当前在线人数……”。
接下来使用分布式测速服务,例如上面的17ce,还有webkaka,360的。
以上面17ce的测试结果为例,从解析IP所在地字段可以找到许多个省份的服务器,选一个QQ在线图中较暗的省(西藏你不用考虑,因为我目前没见过有公开销售那边的服务器的IDC,所以大麦网使用那边服务器的可能性极低),且要在测试结果的解析IP所在地字段中有该省。

这里我选了黑龙江(选哪个省根据具体情况而定,你不一定要选黑龙江),可以看到有这个服务器:
联通:218.7.220.59

这个省在17ce仅找到了ISP为联通的,可能有些省有多个ISP,不一定要选和你同ISP的,选择同ISP只是可以确保延迟较低,但一般是几个路由,数十毫秒的差距,一般认为南方使用电信的人较多,北方使用联通的人较多,实际使用比例是否如此我就没统计过啦。
接下来编辑hosts文件。
我知道很多人不知道hosts文件是什么,可以点击开始->运行,Windows下输入:

这样就会使用记事本打开hosts文件。
Linux或Unix(Mac OS)的hosts文件在/etc/hosts,自行选择喜欢的编辑器,我喜欢vim,当然你得有root权限。
在末尾新建一行,写入记录(Windows, Linux, Unix均如此):

如图:

hosts

然后保存。由于DNS查询,默认是hosts文件优先(除非你自己改了优先级),因此我们系统获取到shopping.damai.cn的IP将会是218.7.220.59。
验证方法,使用Windows的,在运行的编辑框中输入:

按确定
使用Linux, Unix的,在终端中输入:

按Enter
如果你会nslookup,也可以使用nslookup。
你就可以看到相应的IP,如图:

ping

之后,你访问shopping.damai.cn,就会使用位于黑龙江的服务器。

也许有人留意到了,大麦网有海外的服务器,会不会海外的服务器更少人访问?
这个我是无法确定的,不排除大麦网让所有海外服务器共同使用一个处理订票数据的服务器,甚至该服务器还与国内一个或多个省共用。

毕竟实践是检验真理的唯一标准,因为我没经过测试,只是根据我的理论给出的方案,所以我不敢肯定此方法一定有效。

不过嘛,试试也无妨。

接下来给出另一个方案。
先看看这个图(大家不要生气,我没成功购票,可能是因为我在广东省的原因吧):

Taylor Swift

相信一部分当时盯着大麦网Taylor Swift 1989演唱会的购票页面的人会好奇,为什么倒计时还在进行,我却可以选票,立即预定按钮还出来了?

其实那个日期选择,价格选择,是通过CSS样式禁用了,“您选择了……”,和立即预定按钮,是通过CSS样式隐藏了。
我们可以通过Chrome浏览器的审查元素功能(很多浏览器都有这个功能),修改HTML元素的类,实现更改样式的目的。

找了一会儿,找到一个还没开始售票的项目:http://item.damai.cn/85215.html
我这里就以此项目为例,首先使用Chrome访问该网页。
大家可以发现此页面的时间,票的价格是无法选择的,且“您选择了……”,和立即预定按钮也无法查看到。
把鼠标移动到”2015.07.25 周六 18:00″上,按鼠标右键,点击审查元素,接下来浏览器会弹出一个审查元素的框,并且自动定位到此处的HTML代码,往上数行,可以找到一行的内容为:

如图画红框的位置:

日期选择

编辑此行(可以先用鼠标左键单击此行,此行会变蓝色,再按F2,就会进入编辑状态,或者按右键,选“Edit as HTML”),把:

修改成:

接下来利用相同的方法,定位到价格选择处的代码,不管你是不是要买最便宜的那张票,都给我定位到最便宜的那张票的代码(其实我是想方便你找代码而已),往上数行,找到代码:

如图画红框的位置:

价格选择-1

把:

修改为:

接下来,你可以定位到你要选购的票的面值的HTML代码,如780,往上数行,找到代码:

如图画红框的位置:

价格选择-2

把:

修改为:

不管你是否要选购最贵的一张票,你都给我定位到最贵的一张票的代码处,往下数行,找到代码:

如图画红框的位置:

立即预定

把:

修改为:

到这里,大功告成,可以看到页面已发生了变化:

结果

选择好日期,价格,最后你要做的就是等倒计时结束,就像这图:

Taylor Swift

​别想着你已经选择好了日期以及价格,就可以点击立即预定按钮提交,然后付款购票。
这样只是为了能让你节省一两秒选择日期和价格的时间,还有那该死的Javascript去显示“您选择了……”。

那天我购票仅使用了第二个方法,但提交过去,返回的只是500错误,也许是我没使用第一个方法的缘故吧……

已经确定Taylor Swift要在上海加一场演唱会,如果通过审核,希望这两个方法可以协助各位成功购票。

难得高三毕业了,想去看Taylor Swift的演唱会,却买不到最便宜的票。虽然后面有掉出价格高的,但是学生没那么多钱,广东到上海,路费也不少……

OpenSSH Server & FreeRadius Server Authenticate via Lightweight Directory Access Protocol

安装并配置LDAP Server

apt-get update && apt-get -y install slapd ldap-utils

输入LDAP Server的管理员密码(共两次):


 

重新配置LDAP:

dpkg-reconfigure slapd

 

Omit OpenLDAP server configuration? : no

DNS domain name: domain.com


 

NOTE:此处输入的DNS domain将会作为你的基础搜索区分名称(Base DN)。以”.”为分割符,每个”.”都是一个dc。

举个例子:你输入了domain.com,那么你的Base DN就是dc=domain,dc=com,如果输入了hello.world.com,那么你的Base DN就是dc=hello,dc=world,dc=com。

 

Organization name: domain.com

Administrator password:

NOTE:此处输入的管理员密码将会覆盖安装时输入的密码。

Database backend to use: HDB

Do you want the database to be removed when slapd is purged?: No

Move old database?: Yes

Allow LDAPv2 protocol?: No

安装并配置完毕后,会自动创建管理员账号(Bind DN),默认为cn=admin,你的Base DN。

添加Organizational Units(下文简称OU)

此处以分别使用CLI模式添加名称分别为users与groups的OU。

 

保存以下内容到一个文件,例如usersandgroups.ldif:

 

 

NOTE:dn为此Organizational Units的区分名,简单理解成路径,只不过这个路径是从你要找的文件名开始。例如这里的dn: ou=groups,dc=domain,dc=com,则代表groups这个在dc=domain,dc=com这个Base DN的中。再举一个例子:dn: ou=second,ou=first,dc=domain,dc=com,代表second这个OU位于dc=domain,dc=com这个Base DN的first OU中。

 

使用ldapadd添加:

ldapadd -D “cn=admin,dc=domain,dc=com” -xw管理员密码 -f文件名

 

NOTE:-D后面接的是你的管理员账号。

 

看到类似提示:

adding new entry “ou=groups,dc=domain,dc=com”

 

adding new entry “ou=users,dc=domain,dc=com”

则代表添加成功。

可以使用ldapsearch查看:

ldapsearch -x -b “你的Base DN”

 

添加用户与用户组的记录

此处分别使用CLI添加类型为posixGroup的用户组与posixAccount的用户。

保存以下内容到文件,例如newuserandgroup.ldif(请自行修改dn)

 

 

NOTE:有关dn的,前文已做解释,此处不说。cn是该记录在LDAP中的名称,gidNumber是用户组id,memberUid是用户组的名称,givenName是名字,sn是姓,gidNumber是用户要加入的用户组的id,homeDirectory是用户的家目录,loginShell是用户登录入系统时使用的Shell,uidNumber是用户的uid,uid是用户的用户名,userPassword是用户的密码。

 

同样的,使用ldapadd添加记录:

ldapadd -D “你的Base DN” -xw管理员密码 -f文件名

 

Linux使用LDAP作登录验证

安装验证使用的PAM模块,nss模块,以及nscd:

apt-get -y install libnss-ldap libpam-ldap nscd

 

LDAP server Uniform Resource Identifier: ldap://localhost/

NOTE: 一定要把ldapi:///改成ldap://,再输入LDAP Server的IP。

 


 

Distinguished name of the search base: dc=domain,dc=com

NOTE:此处输入你的Base DN。

 

 

LDAP version to use: 3

Make local root Database admin: Yes

Does the LDAP database require login?: No

LDAP account for root: cn=admin,dc=domain,dc=com

NOTE:此处输入你的Bind DN。

LDAP root account password:

 

修改/etc/nsswitch.conf文件,在passwd,group,shadow开头的三行末尾的compat前加入ldap,并以空格与compat分开:


 

修改/etc/pam.d/common-session文件,在末尾加入此行:

 


 

重启nscd:

service nscd restart

 

最后使用已在LDAP Server添加的账号记录登录此系统:

ssh newuser@localhost

 


 

 

 

Freeradius使用LDAP作验证

此处将会启用Freeradius的LDAP模块。

 

NOTE:开始下面步骤前,建议你使用http://soft.yzs.me/freeradius.sh安装FreeRadius Server

 

首先安装freeradius-ldap:

apt-get -y install freeradius-ldap

编辑/etc/freeradius/modules/ldap文件,把server等于号后面的内容改为你的LDAP Server IP,去掉identity前面的”#”,把等于号后面的内容改为你的Bind DN,去掉password前面的”#”,把等于号后面的内容改为你的LDAP Server的管理员密码,把basedn等于号后面的内容更改为你的Base DN,最后去掉password_attribute开头的”#”。

 

修改完毕后的内容应该如下(已去除被注释的行)

 

修改/etc/freeradius/sites-available/default文件。


authorize {

此处内容省略

}

的”{“与”}”之间加入一行:ldap。


authenticate {

此处内容省略

}

的”{“与”}”之间加入下面内容:

Auth-Type LDAP {

ldap

}

 

如果使用http://soft.yzs.me/freeradius.sh安装FreeRadius Server,则修改完毕后/etc/freeradius/sites-available/default文件的内容一般如下:

 

 

重启Freeradius:

service freeradius restart

 

最后使用radtest,对已在LDAP Server添加的用户记录进行测试:

radtest newuser newuser localhost 0 testing123

 

如果返回的内容有Access-Accept,则代表验证成功:

Sending Access-Request of id 27 to 127.0.0.1 port 1812

User-Name = “newuser”

User-Password = “newuser”

NAS-IP-Address = 208.51.63.112

NAS-Port = 0

rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=27, length=20

 

教程到此完毕,感谢阅读。

云雾互联以及微宇宙的管理员——Extreme制作。

 

QQ:865475185

Email:e@yzs.me

 

除非另有声明,本文档内容采用知识共享署名-非商业性使用-相同方式共享授权。

让cPanel/WHM的Apache使用PHP FPM

因为FasiCGI,CGI模式下均有少许问题,所以一直以来都给Apache使用mod_php方式执行PHP。

但此模式的资源占用可要给差评了,在网站访问量大的时候,特别是被CC的时候,FORK出的大量Apache进程经常会变成“僵尸”进程,无法正常退出,即使访问量恢复正常,攻击已结束,那些“僵尸”进程一样占用着你的资源,有时攻击猛烈些,直接整个系统宕掉,非硬重启无法救活。纵使有些人会使用如CloudLinux,BetterLinux之类的限制单用户的进程,但还是会有以Apache默认的执行身份fork出的进程……

为了给虚拟主机带来更稳定,更安全的使用环境,必须更换PHP执行方式!

经过测试与研究,最后采用了PHP FPM。

WHY PHP FPM?

PHP FPM不仅能满足使用admin value,opcache的需求,还能针对每个不同的pool的最大进程数量进行限制。这也就意味着,可以防止某个站点占用服务器过多的资源。

同时,让Apache使用worker模式运行,仅负责静态资源,仅需数个进程就能处理大量的访问。

可见,PHP FPM性能,安全皆具备!

 

很可惜,一直以“强大”著称的cPanel/WHM的,在PHP设置的选项中并没有表现出任何的强大:

Configure PHP and suEXEC

 

 

很明显,这要自己动手了。

 

动手前,先定一个大概的步骤:

1. 切换Apache为worker模式。

2. 编译安装PHP。

3. 给cPanel/WHM添加HOOK。

4. 给已有的用户创建PHP FPM POOL配置文件。

5. 重建所有站点的Apache配置文件。

 

因为服务器有已有虚拟主机的用户,因此“改造”过程中尽量减少Apache的暂停时间。

 

切换Apache为worker模式

看了一下cPanel/WHM编译Apache的的参数,是使用–with-mpm指定mpm模块的,要更换的话,只能重新编译。EasyApache中并未mod_proxy_fcgi,要让Apache使用FastCGI Server,此模块是必须的。

既然如此,那自行编译是最好不过的选择了。

下载Apache,APR,APR-UTILS:

开始编译:

configure的参数,你可以根据自己的需要做出修改。

这里不能重启Apache,否则无法启动了。

编辑/etc/httpd/conf/includes/pre_main_global.conf文件,在里面加入下列代码:

这样,就成功切换Apache为worker模式运行,并启用mod_proxy_fcgi模块。

由于是自行编译的Apache,如果使用/scripts/rebuildhttpdconf,会出现“This tool unavailable until Apache is built by EasyApache 3.x”的提示,编辑/scripts/rebuildhttpdconf文件,把此行:

注释,或者删掉即可。

 

编译安装PHP

这里使用的是PHP 5.4.31:

编译安装,并配置,把下面的代码保存到一个文件,使用“bash 文件名”方式执行

同样的,编译参数你可以自行更改。

 

给cPanel/WHM添加HOOK

根据cPanel/WHM的官方文档,使用HOOK Script实现在成功创建用户后创建PHP FPM的POOL配置文件,以及成功删除用户后PHP FPM POOL配置文件。

编辑/scripts/postwwwacct,加入下列代码:

还有/scripts/postkillacct:

赋予上述文件的执行权限:

 

给已有的用户创建PHP FPM POOL配置文件

用户多的话,手动创建是不可能的,这里提供一个Shell Script:

如果一切无误,启动PHP FPM:

 

重建所有站点的Apache配置文件

先添加一个Apache的用户:

修改cPanel/WHM的Apache配置文件模板,进入/var/cpanel/templates/apache2_4(如果你之前使用的是Apache2.2,应该要进入/var/cpanel/templates/apache2)文件夹,创建自定义配置文件模板:

这样cPanel/WHM就会使用.local结尾的作为模板创建Apache的配置文件。

修改main.local文件,找到此行:

将其更改为:

分别编辑ssl_vhost.local,vhost.local,在文件首行,也就是”<VirtualHost[% FOREACH ipblock IN vhost.ips %] [% ipblock.ip %]:[% ipblock.port %][% END %]>”之前,加入这些代码:

接下来,找到“UserDir enabled [% vhost.user %]”,在他后面三行的“[% END -%]”后加入一行:

如图所示:

ProxyPassMatch

 

完成上述修改后,执行:

重建所有用户的配置文件。

最后,让Apache对配置文件进行检测:

如果出现类似的提示:

那你离成功不远了,访问Configure PHP and suEXEC,把PHP 5 Handler改为none即可:

PHP 5 Handler

一般提交后,WHM会自动帮你重启Apache,不过我这里建议最好还是再使用configtest参数检测一下,并重启Apache。

 

到这里,改造就完成了,可以用雅黑PHP探针对PHP环境进行检测:

雅黑PHP探针

能看到“PHP运行方式”一项为“FPM-FCGI”,那就说明大功告成了。