CentOS 6.7下安装vsftpd FTP服务器经验

最近Wordpress从虚拟主机迁移到了VPS上,原来虚拟主机服务商有提供FTP,现在VPS需要自己安装一个FTP服务器来支持Wordpress的插件和主题升级。vsftpd是Linux下比较著名的FTP服务器,我选择它搭建FTP服务器。

 

第一步:安装vsftpd

查看你的服务器是否已经安装vsftpd

rpm -qa | grep vsftpd

如果已经安装就略过下一步yum安装。如果没有安装过就执行以下命令:

yum -y install vsftpd

 

第二步:基于虚拟用户的配置

所谓虚拟用户就是没有使用真实的帐户,只是通过映射到真实帐户和设置权限的目的。虚拟用户不能登录CentOS系统。

1. 修改配置文件

打开/etc/vsftpd/vsftpd.conf,修改该文件原来的配置,如下(这里需要一个一个项目在编辑器里查找并修改,注意YES或NO等配置项后面不要在复制过程中多出不必要的空格):

#设定不允许匿名访问
anonymous_enable=NO

#设定本地用户可以访问。注:如使用虚拟宿主用户,在该项目设定为NO的情况下所有虚拟用户将无法访问
local_enable=YES

#使用户不能离开主目录
chroot_list_enable=YES

ascii_upload_enable=YES

#设定支持ASCII模式的上传和下载功能
ascii_download_enable=YES

#PAM认证文件名。PAM将根据/etc/pam.d/vsftpd进行认证
pam_service_name=vsftpd

以下这些是关于vsftpd虚拟用户支持的重要配置项,默认vsftpd.conf中不包含这些设定项目,需要自己手动添加到/etc/vsftpd/vsftpd.conf中:

#设定启用虚拟用户功能
guest_enable=YES

#指定虚拟用户的宿主用户,CentOS中已经有内置的ftp用户了
guest_username=ftp

#设定虚拟用户个人vsftp的CentOS FTP服务文件存放路径。存放虚拟用户个性的CentOS FTP服务文件(配置文件名=虚拟用户名
user_config_dir=/etc/vsftpd/vuser_conf

 

2. 进行认证

首先,安装Berkeley DB工具,很多人找不到db_load的问题就是没有安装这个包。

yum install db4 db4-utils

然后,创建用户密码文本/etc/vsftpd/vuser_passwd.txt ,注意奇行是用户名,偶行是密码:

wordpress
123456

接着,生成虚拟用户认证的db文件:

db_load -T -t hash -f /etc/vsftpd/vuser_passwd.txt /etc/vsftpd/vuser_passwd.db

随后,编辑认证文件/etc/pam.d/vsftpd,全部注释掉原来语句,再增加以下两句:

auth required pam_userdb.so db=/etc/vsftpd/vuser_passwd
account required pam_userdb.so db=/etc/vsftpd/vuser_passwd

最后,创建虚拟用户配置文件:

mkdir /etc/vsftpd/vuser_conf/
vi /etc/vsftpd/vuser_conf/wordpress  //文件名等于vuser_passwd.txt里面的账户名,否则下面设置无效

内容如下(这里需要注意YES或NO等配置项后面不要在复制过程中多出不必要的空格):

local_root=/home/wwwroot
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES

 

3. 设置Selinux(可省略)

setsebool -P ftp_home_dir=1   //设置ftp可以使用home目录
setsebool -P allow_ftpd_full_access=1   //设置ftp用户可以有所有权限

 

4. 设置FTP根目录权限

mkdir /home/wwwroot   //创建目录,如果目录已存在请省略
chmod a-w /home
chmod -R 777 /home/wwwroot

最新的vsftpd要求对主目录不能有写的权限所以/home为a-w,主目录下面的子目录再设置777权限。

 

5. 设置防火墙

打开/etc/sysconfig/iptables,添加一句:

-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT

然后保存,并关闭该文件,在终端内运行下面的命令,刷新防火墙配置:

service iptables restart

启动FTP服务器:

service vsftpd start

 

6. 连接FTP服务器

现在你就可以使用FTP工具连接服务器了,建议使用FileZilla工具连接,连接的过程中如果出现报错,你只需要去搜索报错的内容调整服务器的配置就好了。

 

参考文章:http://www.cnblogs.com/xiongpq/p/3384759.html

一次JVM引起的服务器load过高问题排查经历

2016-11-08早上9:25分,公司运维的同事给我报警,称我们团队的一台服务器CPU的压力很大,zabbix的图显示:

1接到警报后,我在该服务器上使用w和top命令查看服务器的load和CPU情况,1分钟的load average在3-5之间,系统在高负荷运转,查看了我们的线上应用系统发现网页打开正常,但一个別列表的查询缓慢,chrome浏览器的network查看http接口的timing在十几秒。这部分列表走的是搜索引擎,我第一反应是会不会是搜索引擎出问题了?

于是我在服务器上查看tomcat日志,获取我们的应用调用搜索引擎的接口和参数,拼装后使用

curl -v '$url'

命令访问,发现访问的速度没有问题。那说明搜索引擎没有问题,那一定是我们的应用从搜索引擎返回值到展示给用户的部分处理有问题。

由于有大量用户反馈系统速度慢,于是我使用jps获取java进程的pid,随后使用:

jmap -dump:format=b,file=crm.bin [pid]

命令dump jvm的信息“保留犯罪现场”,然后重启线上应用。

启动应用后检测到服务器的load渐渐越来越高,最后保持在重启前的样子,于是使用

jstat -gc [pid] 3000

查看服务器每隔3秒的gc情况,发现3秒钟的full gc能够达到两次,jvm的状况十分异常。在启动服务器的这个时间里我利用eclipse MAT工具分析jmap dump文件信息,未诊断出异常。

后来我把原来jvm的Xms参数配置由1024m提高到3072m,发现双机的full gc次数分别稳定在0和2后再也没有full gc过了,但是young GC却十分频繁,3秒钟young GC次数可以达到15-20次。

到底是什么东西这么占内存???我使用jmap -histo pid查看,发现排在第一位的[C对象经常飙升到1个多G然后降到200MB,就是young GC频繁的原因,这通常是String类型的对象存在问题。

随后我使用

top -H -p [pid]

看到了如下结果:

2这一排的PID都占用了大量的CPU资源,于是随机取了一个PID为1077的进程,使用

printf "%x\n" 1077

转换成16进制的数字为435

随后使用jstack工具:

jstack [pid] | less

输出当前的堆栈信息,然后搜索435,发现如下内容:

3这块代码就是调用搜索引擎的代码,它处于RUNNABLE的状态,一直在执行中,说明这段代码一定是追魁祸首!打开代码看看!原来是这样的一段代码:

while ((line = in.readline()) != null) {
    result += line;
}

真相就是:循环里每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。

将String改成StringBuilder,发布上线后load过高的问题解决。这就解释了为什么一般的页面打开速度正常,而搜索客户列表接口速度缓慢以及为什么char类型的数组占用大量内存。

Nginx报错open failed 13: Permission denied while reading upstream的解决方法

今天我们的系统出现了一个很诡异的情况,一个页面里有几个js文件和图片无法读到,Chrome浏览器里的status是:net::ERR_CONTENT_LENGTH_MISMATCH。而同一个页面其他的js、css和图片都没有问题,status是200。

遇到这个问题我第一反应是这个系统的tomcat我们也没有人动过,这几个资源文件在服务上是用的,那就是看看Nginx有没有问题,刚好今天有人动过Nginx,那就就去看看Nginx的access.log和error.log的日志。发现error.log里面有一个报错:

2016/06/05 17:58:06 [crit] 1017#0: *182 open() “/usr/local/nginx/proxy_temp/4/02/0000000024” failed (13: Permission denied) while reading upstream, client: ***.***.***.***, server: *****, request: “GET /idp/resources/images/mitreid-connect.ico HTTP/1.1”, upstream: “https://*****:8444/idp/resources/images/mitreid-connect.ico”, host: “*****”, referrer: “******”

proxy_temp目录是干什么的?我们的Nginx有个配置proxy_temp_file_write_size,当文件超过该参数设置的大小时,Nginx会先将文件写入临时目录,默认为Nginx安装目下/proxy_temp目录。

默认情况下,nginx是以www启动的,用ll命令查看proxy_temp目录,我们发现用户和用户组是nobody,难怪Permission denied!

我们用

chown -R www:www proxy_temp

把proxy_temp目录改成nobody的用户组权限,重启Nginx后问题就解决了!

php执行Linux命令的方法(具体案例)

最近本人在做一个系统用来管理团队的任务,其中涉及到我们的任务需要选择项目的git分支,我的方案是利用php去获取某个项目的远程仓库的分支:
exec(“cd /data/www/superb/Git/saint;git pull;git branch -r”, $output);
解释下:
cd /data/www/superb/Git/saint # 跳到从git项目拉下来的代码目录下
git pull  # 更新代码
git branch -r  # 获取当前代码目录下本地和远程所有的代码
一句话执行以上三句需要加上分号。
后来发现git pull无效的问题,即服务器的代码目录并没有自动更新,我获取的远程分支不是最新的。后来发现原来是没有权限,因为git pull这种的写操作无法执行,而git branch这样的读操作是可以执行的。
我的服务器是nginx+php-fpm,最终执行这个linux shell命令的用户是php-fpm的www,使用ps aux | grep php-fpm查看,而且我用php exec执行了whoami:
exec(“whoami”, $output);
也证明了用户是www,于是我将www用户添加到了服务器的sudo列表里:
vim /etc/sudoers
增加一行:
www             ALL=(ALL)       NOPASSWD:ALL
# www             ALL=(ALL)       ALL
下面一行注释掉的和第一行的区别是第一行的配置当www用户在执行sudo操作的时候不需要密码,第二行的配置是所有的sudo操作都要输入www用户的密码。
我把php的代码改成了:
exec(“cd /data/www/superb/Git/saint;sudo git pull;git branch -r”, $output); // git pull用sudo来执行
结果发现依然没有效果,最后我只好用下下策,将/data/www/superb/Git/saint目录和子目录文件的用户和组改为了www:
chown -R www:www  /data/www/superb/Git/saint/
最终php的命令改为:
exec(“cd /data/www/superb/Git/saint;git pull;git branch -r”, $output); // 把sudo去掉
这样就可以执行了,最终实现了我的目标。

IDEA集成开发工具Debug Cannot start Maven问题解决方法

最近接手了一个新的JAVA项目,在IDEA中配置好了Debug了,点击Debug,在控制台报错如下:

[FATAL_ERROR] Cannot start Maven: No valid Maven installation found. Either set the home directory in the <a href="#">configuration dialog</a> or set the M2_HOME environment variable on your system.

我以前的项目都可以正常使用Maven,这个项目居然不能使用了,我的~/.zshrc一切配置都正常,真是奇怪了。后来去stackoverflow上查了下,原来是Mac的Shell环境变量未必能够被GUI应用读到。解决方法如下:

sudo vim /etc/launchd.conf  //一般Mac上默认是没有这个文件的

在这个文件中加上你的M2_HOME的配置:

setenv M2_HOME /usr/local/maven/apache-maven-3.2.1

然后你一定要重新启动Mac这个配置才会生效,重启之后Debug就正常了。