Rootop 服务器运维与web架构

2019-12-16
发表者 Venus
nginx反向代理加防盗链配置已关闭评论

nginx反向代理加防盗链配置

# 配置例子

server
{
	listen   80;
	server_name  www.rootop.org;

	root /home/web/www.rootop.org;
	
	location ~ .*\.(jpg|png|js|css)$
	{
		valid_referers none blocked server_names rootop.org;
		if ($invalid_referer)
		{
			return 404;
		}
		
		proxy_pass http://127.0.0.1:8080;
	}
	
	location /
	{
		proxy_pass http://127.0.0.1:8080;
	}
}

# 注意在防盗链的location中也要加一句proxy_pass,否则图片会从本地找,肯定会返回404状态码。

location ~ .*\.(jpg|png|js|css)$
{
	valid_referers none blocked server_names rootop.org;
	if ($invalid_referer)
	{
		return 404;
	}
	
	proxy_pass http://127.0.0.1:8080;
}

如果不加proxy_pass,在return 404这个地方很容易扰乱排错思路,以为是防盗链返回的404,实际是从本地找不到文件才返回的404.

# 防盗链参数解释

valid_referers 定义一个防盗链白名单
none 表示http请求头中没有Referer这个头信息
blocked 表示http请求头中虽然有Referer头信息,但是中间被防火墙或者被代理服务器删除。
server_names 表示设置的server_name
rootop.org 表示允许的Referer,支持通配符,也支持正则

符合以上条件的,nginx会将$invalid_referer这个内置变量的值设置为空字符串。
不符合的,也就是说Referer头信息不符合以上条件,比如 baidu.com,则会将$invalid_referer变量设置为1
这样通过if条件判断进行返回状态码,或者重定向到其他页面,比如一张图片。

参考官方文档:http://nginx.org/en/docs/http/ngx_http_referer_module.html#valid_referers

2019-12-15
发表者 Venus
nginx if多条件判断的实现已关闭评论

nginx if多条件判断的实现

if判断本身不支持多条件判断,用不了 && 或者|| 这种逻辑运算,而且if也不支持嵌套。
可以通过set变量来迂回实现。

比如这里我要实现访问a.rootop.org跳转到匹配子域名到指定的html页面。
dns和nginx已经配置了泛域名

实现效果:
a.rootop.org -> rootop.org/pages/a.html
b.rootop.org -> rootop.org/pages/b.html

但是这里要排除www.rootop.org的跳转

server
{
	listen 80;
	server_name rootop.org www.rootop.org *.rootop.org;
	root html;
	
	# 子域名跳转指定html页面
	# 先设置个变量
	set $subdomain "";
	
	# 正则获取三级域(也就是主机名)
	if ($http_host ~* "^(.*)\.rootop\.org$")
	{
		set $subdomain $1;
	}

	# 排除www
	if ($subdomain = "www")
	{
		set $subdomain "";
	}

	# 除www外的实现跳转
	if ($subdomain != "")
	{
		# 注意加上$scheme,如果是rootop.org/pages/xxx.html,则会认为是在域名后面加了个目录地址。
		return 301 $scheme://rootop.org/pages/$subdomain.html;
	}
}

如果想反过来实现也可以

# html页面跳转子域名
if ($uri ~* ".*/pages/(.*)\.html")
{
	return 301 $scheme://$1.rootop.org;
}

2019-12-11
发表者 Venus
supervisor安装及配置已关闭评论

supervisor安装及配置

# 安装

[root@VM_0_7_centos ~]# yum install -y supervisor

# 查看释放了哪些文件

[root@VM_0_7_centos ~]# rpm -ql supervisor-3.1.4-1.el7.noarch
/etc/logrotate.d/supervisor
/etc/supervisord.conf
/etc/supervisord.d
/etc/tmpfiles.d/supervisor.conf
/usr/bin/echo_supervisord_conf
/usr/bin/pidproxy
/usr/bin/supervisorctl
/usr/bin/supervisord
略···

可以看出/etc/supervisord.conf是主配置文件。

[root@VM_0_7_centos ~]# cat /etc/supervisord.conf | grep -vE "^;|^$"
[unix_http_server]
file=/var/run/supervisor/supervisor.sock   ; (the path to the socket file)
[inet_http_server]         ; inet (TCP) server disabled by default
port=*:9001        ; (ip_address:port specifier, *:port for all iface)
username=root              ; (default is no username (open server))
password=root               ; (default is no password (open server))
[supervisord]
logfile=/var/log/supervisor/supervisord.log  ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB       ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10          ; (num of main logfile rotation backups;default 10)
loglevel=info               ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false              ; (start in foreground if true;default false)
minfds=1024                 ; (min. avail startup file descriptors;default 1024)
minprocs=200                ; (min. avail process descriptors;default 200)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock ; use a unix:// URL  for a unix socket
[include]
files = supervisord.d/*.ini

# 解释

[inet_http_server]
port=*:9001
username=root
password=root

这4行去掉前面的注释后,即为开启web端管理,默认端口9001,supervisor提供了一个简易的管理界面。

files = supervisord.d/*.ini

这行表明启动时加载supervisord.d目录下的所有ini文件,这样可以把要管理的程序独立配置。

# 添加一个shell脚本测试

[root@VM_0_7_centos ~]# cat test.sh 
#!/bin/bash

for i in {1..20}
do
	current_time=`date`
	echo $current_time
	sleep 1
done

循环20次,打印当前时间

# 创建配置文件

[root@VM_0_7_centos ~]# cd /etc/supervisord.d/
[root@VM_0_7_centos supervisord.d]# vi test_script_supervisor.ini
[program:test]
command=/root/test.sh           
directory=/root             
priority=999  
autostart=true         
autorestart=true 
startsecs=5
startretries=3
user=root       

配置参数含义可以参考主配置文件中的配置案例,每个参数后面都带着解释。或者百度可以找到。
# 看一下supervisorctl命令用法

[root@VM_0_7_centos supervisord.d]# supervisorctl --help
supervisorctl -- control applications run by supervisord from the cmd line.

Usage: /usr/bin/supervisorctl [options] [action [arguments]]

Options:
-c/--configuration -- configuration file path (default /etc/supervisord.conf)
-h/--help -- print usage message and exit
-i/--interactive -- start an interactive shell after executing commands
-s/--serverurl URL -- URL on which supervisord server is listening
     (default "http://localhost:9001").
-u/--username -- username to use for authentication with server
-p/--password -- password to use for authentication with server
-r/--history-file -- keep a readline history (if readline is available)

action [arguments] -- see below

Actions are commands like "tail" or "stop".  If -i is specified or no action is
specified on the command line, a "shell" interpreting actions typed
interactively is started.  Use the action "help" to find out about available
actions.

[root@VM_0_7_centos supervisord.d]# supervisorctl help

default commands (type help <topic>):
=====================================
add    clear  fg        open  quit    remove  restart   start   stop  update 
avail  exit   maintail  pid   reload  reread  shutdown  status  tail  version
上面为支持的动作

[root@VM_0_7_centos supervisord.d]# supervisorctl help update
update			Reload config and add/remove as necessary
update all		Reload config and add/remove as necessary
update <gname> [...]	Update specific groups

# 重载supervisor配置

[root@VM_0_7_centos supervisord.d]# supervisorctl update
test: added process group
[root@VM_0_7_centos supervisord.d]# supervisorctl status
test                             FATAL     command at '/root/test.sh' is not executable 

# 通过 supervisorctl status 加配置中 program 后面的名字可以查看添加的服务状态

[root@VM_0_7_centos supervisord.d]# supervisorctl status test
test                             FATAL     command at '/root/test.sh' is not executable

看到提示致命错误,提示不可执行。说明没有执行权限。

[root@VM_0_7_centos supervisord.d]# chmod 700 /root/test.sh  # 我是用root权限执行,所以给了个700权限
[root@VM_0_7_centos supervisord.d]# supervisorctl start test
test: started
[root@VM_0_7_centos supervisord.d]# supervisorctl status test
test                             RUNNING   pid 19487, uptime 0:00:07
[root@VM_0_7_centos supervisord.d]# ps aux | grep test
root     19824  0.0  0.0 115308  1504 ?        S    20:25   0:00 /bin/bash /root/test.sh

通过web界面可以查看、管理服务

如果想记录脚本执行日志,可通过/etc/supervisord.conf中的配置案例配置服务的输出日志。

2019-12-10
发表者 Venus
php网站访问提示No input file specified已关闭评论

php网站访问提示No input file specified

访问网站首页index.php提示错误:
No input file specified.

wordpress提示的错误,其实这个错误不仅仅在wp框架下出来,任何php程序都会出现,
我这里出现这个问题是由于开启防跨目录功能导致,此功能一般是防止恶意代码写入到其他网站目录文件,导致挂马之类的攻击。
这个功能由open_basedir参数控制。在php.ini里可配置,在每个网站根目录下的.user.ini也可以配置。
参考:https://www.php.net/manual/zh/configuration.file.per-user.php

查看下此站的 .user.ini 文件:

root@rootop:/home/web/test.rootop.org# cat .user.ini 
open_basedir=/www/wwwroot/test.rootop.org:/tmp

查看php.ini配置:

root@rootop:/etc/php/7.2/fpm# cat php.ini | grep user.ini
; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
;user_ini.filename = ".user.ini"
;user_ini.filename =
;user_ini.cache_ttl = 300

在nginx中日志会体现为:

2019/12/10 17:55:28 [error] 25190#0: *1062213 FastCGI sent in stderr: "PHP message: PHP Warning:  Unknown: open_basedir restriction in effect. File(/home/web/test.rootop.org/index.php) is not within the allowed path(s): (/www/wwwroot/test.rootop.org:/tmp) in Unknown on line 0
PHP message: PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0
Unable to open primary script: /home/web/test.rootop.org/index.php (Operation not permitted)" while reading response header from upstream, client: 223.104.210.230, server: test.rootop.org, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.2-fpm.sock:", host: "test.rootop.org"

解决方法:
要么直接删除.user.ini,要么修改为正确的防跨目录路径(正确的网站目录路径)。

另外出现此错误,也有可能是其他原因导致,需要从日志里排查。

2019-12-10
发表者 Venus
centos修改密码提示 authentication token manipulation error已关闭评论

centos修改密码提示 authentication token manipulation error

在centos单用户模式下修改root密码提示错误:
authentication token manipulation error

分析是修改密码时要去修改/etc/shadow文件,但是此文件可能出现问题,不能被修改,查看特殊权限(lsattr)里面被添加了一个a位
a位代表append only,只能追加数据,不能修改数据,所以修改密码时报错。

测试a位作用:

root@rootop:~# touch a
root@rootop:~# chattr +a a
root@rootop:~# lsattr a
-----a--------e--- a
root@rootop:~# echo a > a
-bash: a: Operation not permitted
# 提示操作不允许
root@rootop:~# echo a >> a
root@rootop:~# cat a
a
# 追加数据可以

上面a文件的e位在man文档中解释:
extent format (e)
The ‘e’ attribute indicates that the file is using extents for mapping the blocks on disk. It may not be removed using chattr(1).
“e”属性位表示文件正在使用区段映射磁盘上的块。不能使用chattr删除此位。

所以上面的问题,通过chattr去掉a位权限即可。
为什么会多出来个a位权限?
排查是服务器被黑了。