TracFone Wireless 是美国规模比较大的MVNO,也就是大家所说的MVNO运营商,他旗下有很多的品牌: NET 10 wireless, Safelink wireless, Straight talk, Total Wireless, Simple Mobile, Page Plus Celluar, GoSmart Mobile, Walmart Family Mobile 等等
Centos 7 Postfix使用第三方的smtp
参见前一篇文章,阿里云的ecs全部关闭了25端口,因此我们只能使用postfix来通过第三方的smtp服务发送一些系统邮件,比如说报警邮件.
这些第三方服务商一般提供25,587端口的smtp的服务,这里我们选择使用587端口
假设你的服务器的hostname是beta.iamhippo.com, 在/etc/aliases 中设定
root [email protected]
表示所有发向root的邮件都转发到[email protected], 下面是详细的步骤:
1) 安装必须的library
centos/redhat/fedora:
yum install cyrus-sasl-plain
debian/ubuntu:
apt-get install libsasl2-modules
如果你不安装cyrus或者libsasl库,你会得到“no mechanism found error”
2) 设置smtp的用户名,密码
postfix的smtp的用户名和密码位于/etc/postfix/sasl_password
vi /etc/postfix/sasl_password
按照下面的格式添加验证信息:
[mail.isp.example]:587 username:password
我们需要hash一些这个文件来给postfix使用
postmap /etc/postfix/sasl_passwd
一切都正常的情况下,你会在这个目录/etc/postfix目录下看到sasl_passwd.db文件
必要的安全设置:
chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
3) 设置generic map
如果我们是通过配置csf,让系统自动发送报警邮件,那么一般是来自于[email protected], 我们想在邮件中替换这个邮件的话,可以使用generic的功能,比如说我们想把[email protected] 改成[email protected], 那么可以这么写:
[email protected] [email protected]
然后和sasl_password 一样,我们需要hash 一下
postmap /etc/postfix/generic chown root:root /etc/postfix/generic /etc/postfix/generic.db chmod 0600 /etc/postfix/generic /etc/postfix/generic.db
4) 配置reply server
这个配置起来就比较简单了,直接打开/etc/postfix/main.cf文件,在最末尾添加:
# specify SMTP relay host relayhost = [mail.isp.example]:587 # enable SASL authentication smtp_sasl_auth_enable = yes # disallow methods that allow anonymous authentication. smtp_sasl_security_options = noanonymous # where to find sasl_passwd smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd # Enable STARTTLS encryption smtp_use_tls = yes # where to find CA certificates smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt # where to find generic smtp_generic_maps = hash:/etc/postfix/generic
保存配置,然后重启postfix
systemctl restart postfix
当然了,建议在重启之前先把postfix 中的queue mails 都删掉。。要不然积累了大量的邮件会一次性发出的
postsuper -d ALL
或者
postfix -f
或者
postfix flush
查看mail queue:
mailq
阿里云邮件推送的坑
国内的服务器一直在使用阿里云的,没有办法目前的情况下阿里云确实是国内的No.1
阿里云的ecs默认是关掉25端口的,就算是你申请解封25端口成功了,你也无法用25端口发信,他只允许你用25端口连接到其他的smtp服务器来发信.
使用阿里云的服务,自然而然的想到阿里云的邮件推送服务,而且他还赠送一部分免费的额度,对于我们这种只需要发送触发邮件的人来说,这是非常合适的.
但是这里的一个坑就是smtp协议下只支持25,80,465端口,而465端口一般用来支持STARTTLS, 这个协议比较老,国际标准化组织已经不再推荐,很多的程序例如iredmail默认已经不支持这个端口了。如果你使用的是debian,ubuntu的话,那么这是没有任何问题的,因为自带的postfix 的版本相对来说要新很多, 是3.0 的版本,支持465端口. 如果你使用的是centos7 并且使用的是自带的postfix的话,那么恭喜你,你获奖了。。。
centos7自带的postfix的版本相对来说要低很多,是2.10的版本。。。
而且postfix 的2.10的版本,对于465端口,也就是smtps并不是很支持,你需要使用的stunnel的转发smtps的请求. 详细请看这里:
http://www.postfix.org/TLS_README.html#client_smtps
网上铺天盖地的教程都是apt-get, 我想他们可以也没有想到在centos7 里面会出现问题,不值得花时间去演就演stunnel,那么多的提供标准服务的smtp服务商,舍弃阿里云推送就好了.
如果你的网站位于国外,那么你可以使用sendgrid或者mailgun,都是非常的方便
PHP7 兼容性检测
PHP 7 都出到7.4 了,是时候把手中的discuz论坛升级到PHP 7了,考虑了半天兼容性的问题,准备升级到php 7.3
discuz 的主程序已经升级到最新的discuz 20191201版本了,兼容PHP 7.3应该是没有问题,剩下的就是安装的那些插件的兼容性的问题.
检测PHP7 的兼容性,我们这里使用主流的PHPCompatibility 配合PHP Code_Sniffer
https://github.com/squizlabs/PHP_CodeSniffer https://github.com/PHPCompatibility/PHPCompatibility
PHPCompatibility 是PHP Code_Sniffer 的插件,因此我们应该先安装PHP Code_Sniffer, 在github上有很多中的安装方式,这里我们选择最近的wget 或者curl下载二进制程序,然后把二进制程序放到全局去
# Download using curl
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
# Or download using wget
wget https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
wget https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
# register as global commands mv phpcs.phar phpcs mv phpcbf.phar phpcbf chmod 755 phpcs chmod 755 phpcbf mv phpcs /usr/local/bin/ mv phpcbf /usr/local/bin/
这样就安装完了phpcs,下一步我们需要下载PHPCompatibility这个插件,并且让phpcs使用这个插件
# Download PHPCompability cd ~ wget https://github.com/PHPCompatibility/PHPCompatibility/archive/9.3.5.zip unzip 9.3.5.zip # path is /root/PHPCompability9.3.5 # config phpcs to use PHPCompatibility phpcs --config-set installed_paths /root/PHPCompability9.3.5
这样phpcs就可以使用PHPCompatibility9.3.5了,当然了也可以使用git的形式来下载,这样更新PHPCompatibility比较方便
加入说我们需要检查的文件folder 是/home/plugin, 那么我们就可以用
phpcs -p --standard=PHPCompatibility --runtime-set testVersion 7.3 --report-full=/home/php.log /home/plugin
-p: 打印progress到console上面
–standard: 表示使用哪个标准
–runtime-set testVersion 7.3 : 表示用PHP7.3的标准来检查
–report-full: 表示将结果输出到某一文件
检查完毕,删掉了不兼容php7.3 的插件,然后就开始准备升级discuz到7.3了
AWS Lightsail Singapore Benchmark
AWS对于IO的限制,配置越高,限制越少,这里我们benchmark 一下80刀的这一款,4 cores,16GB RAM, 320GB SSD
测试使用的程序:
wget -qO- bench.sh | bash
下面是结果:
---------------------------------------------------------------------- CPU model : Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz Number of cores : 4 CPU frequency : 2399.858 MHz Total size of Disk : 320.0 GB (1.1 GB Used) Total amount of Mem : 15883 MB (171 MB Used) Total amount of Swap : 0 MB (0 MB Used) System uptime : 0 days, 0 hour 9 min Load average : 0.15, 0.15, 0.09 OS : CentOS 7.6.1810 Arch : x86_64 (64 Bit) Kernel : 3.10.0-957.1.3.el7.x86_64 ---------------------------------------------------------------------- I/O speed(1st run) : 134 MB/s I/O speed(2nd run) : 130 MB/s I/O speed(3rd run) : 130 MB/s Average I/O speed : 131.3 MB/s ----------------------------------------------------------------------
测试了几次,基本都是这个IO速度
PHP SimpleXMLElement 对象
今天在用RedbeanPHP 写数据库接口的时候,发现从SimpleXMLElement对象里面出来的值,按理说都是string, 怎么也不能赋值给RedbeanPHP, 用var_dump看了一下,发现SimpleXMLElement对象比较有意思,里面嵌套的对象以及property 的type 都是object,而且都是SimpleXMLElement 对象,在google上搜了一下发现问这个问题的不少。
https://stackoverflow.com/questions/416548/forcing-a-simplexml-object-to-a-string-regardless-of-context
比如说XML是这样的:
<channel> <item> <title>This is title 1</title> </item> </channel>
下面这样确实能够输出string:
$xml = simplexml_load_string($xmlstring); echo $xml->channel->item->title;
但是除了echo 以外,下面这样就不能被当成string了
$foo = array( $xml->channel->item->title );
这是因为$XML->channel->item->title 的type 其实仍然为SimpleXMLElement的对象
我们可以用typecast来解决这个问题:
$foo = array( (string) $xml->channel->item->title );
The above code internally calls __toString() on the SimpleXMLObject. This method is not publicly available, as it interferes with the mapping scheme of the SimpleXMLObject, but it can still be invoked in the above manner.
另外看到有人这么写也可以:
$foo = array( $xml->channel->item->title.'' );
通过gettype查看确实变成了string,具体原理不知道
Bootstrap 4 在线布局工具
https://www.layoutit.com/build (推荐,全栈开发者的福气) http://shoelace.io/ (比较简陋) https://bootstrapstudio.io/ (需要购买)
利用AWK来分析nginx日志
分析nginx日志有各种各样的可视化工具,但是这样比较繁琐,需要安装和配置,大部分的时候我们只需要简单的分析,这里awk 完全可以满足我们的需求。
- 统计日志中访问最多的10个ip
方法一
awk '{a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
方法二
awk '{print $1}' access.log |sort |uniq -c |sort -k1 -nr |head -n10
2. 统计日志中访问大于100次的IP
方法一
awk '{a[$1]++}END{for(i in a){if(a[i]>100)print i,a[i]}}' access.log
方法二
awk '{a[$1]++;if(a[$1]>100){b[$1]++}}END{for(i in b){print i,a[i]}}' access.log
3. 统计2019年12月24日一天内访问最多的10个IP
方法一
awk '$4>="[24/Dec/2019:00:00:01" && $4<="[24/Dec/2019:23:59:59" {a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
方法二
sed -n '/\[24\/Dec\/2019:00:00:01/,/\[24\/Dec\/2019:23:59:59/p' access.log |sort |uniq -c |sort -k1 -nr |head -n10
4. 统计访问最多的前10个页面 ($request)
awk '{a[$7]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}' access.log
5. 统计蜘蛛抓取次数
grep 'Baiduspider' access.log |wc -l
统计蜘蛛抓取404的次数
grep 'Baiduspider' access.log |grep '404' | wc -l
Cloudflare 配合nginx 来禁止某些国家, user agent 的访问
其实目前cloudflare 的免费版已经在control panel 里面可以完美的实现这些功能,但是cloudflare 能做到的只是禁止某些国家或者user agent 的访问,如果我们想更好的优化这些流量,比如说对不同的geo跳转到不同的网站,或者对于某些蜘蛛来说显示不同的网站,那么就需要nginx 的配合了, 在这里我们主要利用的是nginx 的map 这个功能.
对于geo 的控制
如果你的网站在cloudflare 的保护下,那么cloudflare 默认会在header里面加上’HTTP_CF_IPCOUNTRY’, 这就相当于cloudflare 提供了免费的IP数据库,利用nginx 的map 功能,比如说禁止来自US, CA, UK, AU的流量, 那就就可以按照如下配置:
在nginx 的全局中
map $http_cf_ipcountry $allow { default yes; US no; CA no; UK no; AU no; }
在server中
if ($allow = no) { return 403; }
在这里需要注意的是,按照nginx 的官方文档,map 只能位于http block里面,return 就比较自由了,可以在server,location block里面
深入一点,return的可以不仅仅是403,还可以是301, 302等等,比如说把US,CA,UK和 AU 的流量跳转到google,可以这么配置:
if ($allow = no) { return 301 https://www.google.com; }
在更加深入一点,活用map功能,我们可以不仅仅是map GEO,还可以map user agent等等,这里就需要正则的配合了.
Centos 7 编译安装nginx
基本说明见这里: https://www.iamhippo.com/2019-12/1167.html
1) update system and install building software
yum clean all yum update -y
disable selinux
vi /etc/selinux/config reboot yum groupinstall -y 'Development Tools'
2) add nginx username and group, identical to the one nginx offical repo creates:
useradd --system --home /var/cache/nginx --shell /sbin/nologin --comment "nginx user" --user-group nginx
check user and group created
3) download nginx dependencies source code
cd ~ wget https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz && tar xzvf pcre-8.43.tar.gz wget https://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz wget http://www.openssl.org/source/openssl-1.1.1d.tar.gz && tar xzvf openssl-1.1.1d.tar.gz
wget https://nginx.org/download/nginx-1.16.1.tar.gz && tar zxvf nginx-1.16.1.tar.gz cd nginx-1.16.1 ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-pcre=../pcre-8.43 --with-pcre-jit --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.1.1d --with-openssl-opt=no-nextprotoneg --with-debug
make make install
# go to home
cd ~
# symlink /usr/lib64/nginx/modules to /etc/nginx/modules
ln -s /usr/lib64/nginx/modules /etc/nginx/modules mkdir /var/cache/nginx -p mkdir /etc/nginx/vhost -p
vi /usr/lib/systemd/system/nginx.service
[Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target
reload systemd daemon
systemctl daemon-reload
start service and auto boot
systemctl start nginx systemctl enable nginx
check if nginx startup on reboot
systemctl is-enabled nginx.service
check if nginx is running
systemctl status nginx