Ubuntu 16.04.01 LTS 安装 Nginx PHP MYSQL环境

blog之前运行在Ubuntu 14.04上,虽然是LTS版本不过毕竟新的LTS版本16.04已经出来了这么久,得益于VPS供应商增加了16.04的镜像故找个时间把blog重新安装了一下,这里留下记录仅供参考。

之前服务器使用的apache,不过更新版本的时候考虑到http2的支持,所以服务器这次选择了nginx来作为web服务。
很多网站表示Ubuntu 16.04的nginx不支持http2需要手动编译,然而截止到目前为止仓库里最新的deb包已经默认支持http2。

#运行apt-cache show nginx可以查看nginx包版本
apt-cache show nginx
##################################################################################
Package: nginx
Version: 1.10.0-0ubuntu0.16.04.4
#安装后运行nginx -V可获得nginx的版本信息,可以从获取的信息中看到--with-http_v2_module
#故目前的包版本中已经支持http2,无需额外编译安装

那么直接apt-get一下安装nginx即可

apt-get -y install nginx

然后安装mysql

apt-get -y install mysql-server mysql-client

可以运行一个mysql的安全设置向导mysql_secure_installation进行一些安全性配置。使用脚本可以做到,更改root密码、移除MySQL的匿名用户、禁止root远程登录、删除test数据库。使用上面的这些选项可以提高MySQL的安全。
由于blog的vps配置比较低,所以为了预防内存不足需要修改一下mysqld的配置。
修改/etc/mysql/mysql.conf.d/mysqld.cnf

innodb_buffer_pool_size = 32M

最后安装php,Ubuntu 16.04默认已经是php7了,而不是php5,需要注意一下。

apt-get -y install php php-mysql

安装完成之后需要对nginx做一些配置。Ubuntu下面默认的配置目录是/etc/nginx/。
首先是/etc/nginx/nginx.conf
这里我修改了server_tokens选项为off
server_tokens的作用是隐藏Nginx的版本号,隐藏web服务的版本可以提高攻击难度,有利于提高安全性。

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;
	server_tokens off;
	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}


#mail {
#	# See sample authentication script at:
#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
# 
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}
#}

接着是/etc/nginx/sites-enabled,nginx启动时会读取目录下的所有配置。
我个人删除了/etc/nginx/sites-enabled/default
因为我个人的配置准备直接写在一个文件里,所以就没必要使用default了

rm /etc/nginx/sites-enabled/default
touch /etc/nginx/sites-enabled/exvs

出于安全性考虑,我选择全站强制https,所以80端口只需要做一些跳转工作就行了。配置如下。

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    #几个常见的安全http头
    #HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload";
    add_header Content-Security-Policy "script-src 'self'";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    
    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://www.exvs.org$request_uri;
}

80端口就只有一个作用,返回301跳转到https链接。关于几个常见的安全http头我们大致解释一下。
Strict-Transport-Security(HSTS)
一个网站接受一个HTTP的请求,然后跳转到HTTPS,用户可能在开始跳转前,通过没有加密的方式和服务器对话,比如,用户输入http://example.com,传统的做法是服务器返回301跳转到https://example.com。但是服务器返回301时并不是加密的,这将导致服务器返回的结果容易篡改,从而产生了劫持的现象。启用HSTS后,用户访问网站后浏览器会把网站加入HSTS列表,之后如果再次访问则强制https访问,从而尽可能的避免劫持的产生。
注意的是,一旦启用在参数时间内不能关闭https访问。
Content-Security-Policy
W3C的Content Security Policy,简称 CSP,CSP旨在减少跨站脚本攻击。这里我们配置为Content-Security-Policy: default-src ‘self’
这样可以阻止非本站的资源被浏览器加载,这样即使页面遭到篡改仍然不会加载非本站的元素。
X-Frame-Options
设置这个http头之后将会阻止浏览器通过FRAME加载你的网站页面。
X-XSS-Protection
设置此http头后,如果IE检测到了跨站脚本攻击(Cross-Site Scripting),那么IE将对页面做相应的修改以阻止攻击的发生。

80端口配置好了,那么剩下的就是配置443端口。HTTPS配置起来比较麻烦。
我们选择Nginx其中一个考虑是默认支持http2,启用http2很简单。
listen 443 ssl http2;
只要像这样配置端口即可。
出于安全性考虑,我选择放弃浏览器兼容。
SSLv2和SSLv3目前已经被证明是不安全的了,目前为止最新的TLS标准是1.2。所以我选择只支持TLS1.2。通过如下配置完成。
ssl_protocols TLSv1.2;
注意:只支持TLSv1.2代表着放弃很大部分老旧浏览器,他们将无法访问。
ssl_ciphers用来控制加密协议,放弃低强度的加密算法很显然有助于提高安全性。具体放弃或者应该启用什么样的算法我推荐直接参考https://cipherli.st
或者
https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_certificate
相信大家很熟悉了,TLS证书,我这里选择的是Let’s Encrypt的证书。个人推荐使用acme.sh签发证书。参见github的地址https://github.com/Neilpang/acme.sh
ssl_dhparam
通过DHE密钥,我们能获得更高的安全性.Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器,而且不能被中间人攻击所拦截。
我们可以通过openssl生成一个强DH密钥。

openssl dhparam -out dhparam.pem 4096

做完这些配置如下所示

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl_dhparam /etc/nginx/tls-cert/exvs/dhparam.pem;
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/nginx/tls-cert/exvs/fullchain.pem;
    ssl_certificate_key /etc/nginx/tls-cert/exvs/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;


    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    
    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    #ssl_trusted_certificate /etc/nginx/tls-cert/exvs/root_ca_cert_plus_intermediates;
    #resolver 208.67.222.222 208.67.220.220 valid=300s;
    resolver 208.67.222.222 208.67.220.220;
    resolver_timeout 5s;

    server_name exvs.org;
    return 301 https://www.exvs.org$request_uri;
}

之后我还需要安装phpmyadmin方便配置,一样通过apt-get就可以安装。

apt-get install phpmyadmin php-zip

如果不安装php-zip那么在导入zip格式压缩后的sql数据是会提示“您正在载入不支持的压缩格式”
备注:由于Ubuntu源提供的包版本可能相对较phpmyadmin较为老旧,固推荐使用phpmyadmin官方提供的ppa源来保持更新。关于PPA源的有关信息可参见本站文章https://www.exvs.org/?p=263

剩下的就是站点的配置,包括启用PHP配合Nginx,还有配置phpmyadmin的别名,配置如下。
当然,虚拟机主机不想配置的话直接软连接一下也是可以的。

ln -s /usr/share/phpmyadmin/ /var/www/exvs/phpmyadmin
server {
	listen 443 http2;
	listen [::]:443 http2;
	root /var/www/exvs;

	# Add index.php to the list if you are using PHP
	index index.php index.html index.htm index.nginx-debian.html;
	server_name www.exvs.org;
    
	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

    location ~ /phpmyadmin/.+\.php.*$ {
        if ($fastcgi_script_name ~ /phpmyadmin/(.+\.php.*)$) {
            set $valid_fastcgi_script_name $1;
        }
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /usr/share/phpmyadmin/$valid_fastcgi_script_name;
        include  fastcgi_params;
    }
    location ~ /phpmyadmin/?(.*)$ {
        alias /usr/share/phpmyadmin/$1;
        #root /usr/share/phpmyadmin;
        index index.php;
    }

    # deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	location ~ /\.ht {
		deny all;
	}
    location ~ /.*\.config {
		deny all;
	}
    location ~ /.*\.user\.ini {
		deny all;
	}
    location ~ /wp-config\.php {
		deny all;
	}
    location ~ /wp-config(.*)\.php {
		deny all;
	}
    location ~ /xmlrpc\.php {
		deny all;
	}
    
	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
	#
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
	
	#	# With php7.0-cgi alone:
	#	fastcgi_pass 127.0.0.1:9000;
	#	# With php7.0-fpm:
		fastcgi_pass unix:/run/php/php7.0-fpm.sock;
	}
}

那么到此只需要导入之前wordpress的文件,恢复数据库那么blog就重新配置完成了。
配置完成后最后只需要使用
systemctl restart nginx
重启nginx即可。
配置完成后可以通过ssllabs来检测https的安全性。
https://www.ssllabs.com/ssltest/
如果按照本文进行配置的话,应该会得到A+评级。
https://www.ssllabs.com/ssltest/analyze.html?d=exvs.org

iptables限制连接迸发连接数

由于遇到了迸发连接数太多导致服务器服务器出现问题的案例,这里记录一下使用iptables限制迸发连接数。
这里使用connlimit模块
–connlimit-above n 限制为多少个
–connlimit-mask n 这组主机的掩码,默认是connlimit-mask 32 ,即每ip.也可以是24,16,8这样。
例如:
限制一个IP访问80,443端口最大连接数为16个连接

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 16 -j REJECT
iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 16 -j REJECT

限制一个段访问80,443端口最大为16个连接

iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 --connlimit-mask 24 -j REJECT
iptables -A INPUT -p tcp --syn --dport 443 -m connlimit --connlimit-above 16 --connlimit-mask 24 -j REJECT

Ubuntu下安装使用Spamassassin对Postfix的邮件进行邮件过滤-spampd

系统我这里用的是Ubuntu 16.04 LTS
网上大部分使用spamassassin的说明都是通过调用spamc来完成邮件过滤的,但是如果邮件数量比较多调用spamc需要大量的fork,这个开销比较大,所以这里介绍另一种使用spampd的过滤方法。
如有疑问可参考wiki http://wiki.apache.org/spamassassin/IntegratePostfixViaSpampd
apt-get install spamassassin spamc
添加用户组
groupadd spamd
useradd -g spamd -s /bin/false -d /opt/spamassassin spamd
创建目录修改权限
mkdir /opt/spamassassin
chown spamd:spamd /opt/spamassassin

修改启动配置可以修改
/etc/default/spamassassin
创建SAHOME变量
SAHOME="/opt/spamassassin/"

修改启动选项,由于我需要处理的邮件数量较多,这里做了一定调整

OPTIONS="–create-prefs \
--min-children=4 --max-children=16 --min-spare=4 --timeout-child=30 \
-–username=spamd \
--helper-home-dir ${SAHOME}"

# /etc/default/spamassassin
# Duncan Findlay

# WARNING: please read README.spamd before using.
# There may be security risks.

# If you're using systemd (default for jessie), the ENABLED setting is
# not used. Instead, enable spamd by issuing:
# systemctl enable spamassassin.service
# Change to "1" to enable spamd on systems using sysvinit:
ENABLED=1

# Options
# See man spamd for possible options. The -d option is automatically added.

# SpamAssassin uses a preforking model, so be careful! You need to
# make sure --max-children is not set to anything higher than 5,
# unless you know what you're doing.
SAHOME="/opt/spamassassin/"
OPTIONS="–create-prefs \
 --min-children=8 --max-children=64 --min-spare=8 --timeout-child=30 \
 --username=spamd \
 --helper-home-dir ${SAHOME}"

# Pid file
# Where should spamd write its PID to file? If you use the -u or
# --username option above, this needs to be writable by that user.
# Otherwise, the init script will not be able to shut spamd down.
PIDFILE="/var/run/spamd.pid"

# Set nice level of spamd
#NICE="--nicelevel 15"

# Cronjob
# Set to anything but 0 to enable the cron job to automatically update
# spamassassin's rules on a nightly basis
CRON=0

之后修改spamassassin配置
/etc/spamassassin/local.cf

# This is the right place to customize your installation of SpamAssassin.
#
# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be
# tweaked.
#
# Only a small subset of options are listed below
#
###########################################################################

#   Add *****SPAM***** to the Subject header of spam e-mails
#
# rewrite_header Subject *****SPAM*****


#   Save spam messages as a message/rfc822 MIME attachment instead of
#   modifying the original message (0: off, 2: use text/plain instead)
#
# report_safe 1
report_safe 0
clear_headers
add_header all SPAM-FLAG _YESNO_
add_header all Status score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_

#   Set which networks or hosts are considered 'trusted' by your mail
#   server (i.e. not spammers)
#
# trusted_networks 212.17.35.


#   Set file-locking method (flock is not safe over NFS, but is faster)
#
# lock_method flock


#   Set the threshold at which a message is considered spam (default: 5.0)
#
# required_score 5.0


#   Use Bayesian classifier (default: 1)
#
# use_bayes 1
use_bayes 1

#   Bayesian classifier auto-learning (default: 1)
#
# bayes_auto_learn 1
bayes_auto_learn 1

#   Set headers which may provide inappropriate cues to the Bayesian
#   classifier
#
# bayes_ignore_header X-Bogosity
# bayes_ignore_header X-Spam-Flag
# bayes_ignore_header X-Spam-Status


#   Whether to decode non- UTF-8 and non-ASCII textual parts and recode
#   them to UTF-8 before the text is given over to rules processing.
#
# normalize_charset 1
normalize_charset 1
#   Some shortcircuiting, if the plugin is enabled
# 
ifplugin Mail::SpamAssassin::Plugin::Shortcircuit
#
#   default: strongly-whitelisted mails are *really* whitelisted now, if the
#   shortcircuiting plugin is active, causing early exit to save CPU load.
#   Uncomment to turn this on
#
shortcircuit USER_IN_WHITELIST       on
shortcircuit USER_IN_DEF_WHITELIST   on
# shortcircuit USER_IN_ALL_SPAM_TO     on
# shortcircuit SUBJECT_IN_WHITELIST    on

#   the opposite; blacklisted mails can also save CPU
#
# shortcircuit USER_IN_BLACKLIST       on
# shortcircuit USER_IN_BLACKLIST_TO    on
# shortcircuit SUBJECT_IN_BLACKLIST    on

#   if you have taken the time to correctly specify your "trusted_networks",
#   this is another good way to save CPU
#
# shortcircuit ALL_TRUSTED             on

#   and a well-trained bayes DB can save running rules, too
#
shortcircuit BAYES_99                spam
shortcircuit BAYES_00                ham

endif # Mail::SpamAssassin::Plugin::Shortcircuit

修改完成后可以service spamassassin restart

安装spampd
apt-get install spampd
如果需要修改启动配置可以修改
/etc/default/spampd
这里默认配置没有什么要修改的所以跳过
如果修改完毕可以service spampd restart重启程序

安装postfix
apt-get install postfix
修改/etc/postfix/master.cf
如果需要高迸发数量注意修改maxproc值

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (50)
# ==========================================================================
...
smtp      inet  n       -       n       -       -       smtpd
...
scan               unix    -        -        n        -        10        smtp
localhost:10026    inet    n        -        n        -        10        smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o myhostname=filter.mynetwork.local
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=127.0.0.0/8
spamtnsp          unix  -       n       n       -       -       local

修改完毕后看起来应该是这样

#
# Postfix master process configuration file.  For details on the format
# of the file, see the master(5) manual page (command: "man 5 master" or
# on-line: http://www.postfix.org/master.5.html).
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================
smtp      inet  n       -       y       -       -       smtpd
scan    unix    -       -       n       -       64      smtp
127.0.0.1:10026 inet n  -       n       -       64      smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o myhostname=filter.mynetwork.local
        -o smtpd_helo_restrictions=
        -o smtpd_client_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=127.0.0.0/8
spamtnsp   unix  -       n       n       -       -       local
#smtp      inet  n       -       y       -       1       postscreen
#smtpd     pass  -       -       y       -       -       smtpd
#dnsblog   unix  -       -       y       -       0       dnsblog
#tlsproxy  unix  -       -       y       -       0       tlsproxy
#submission inet n       -       y       -       -       smtpd
#  -o syslog_name=postfix/submission
#  -o smtpd_tls_security_level=encrypt
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#smtps     inet  n       -       y       -       -       smtpd
#  -o syslog_name=postfix/smtps
#  -o smtpd_tls_wrappermode=yes
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#628       inet  n       -       y       -       -       qmqpd
pickup    unix  n       -       y       60      1       pickup
cleanup   unix  n       -       y       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
#qmgr     unix  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       y       1000?   1       tlsmgr
rewrite   unix  -       -       y       -       -       trivial-rewrite
bounce    unix  -       -       y       -       0       bounce
defer     unix  -       -       y       -       0       bounce
trace     unix  -       -       y       -       0       bounce
verify    unix  -       -       y       -       1       verify
flush     unix  n       -       y       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       y       -       -       smtp
relay     unix  -       -       y       -       -       smtp
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       y       -       -       showq
error     unix  -       -       y       -       -       error
retry     unix  -       -       y       -       -       error
discard   unix  -       -       y       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       y       -       -       lmtp
anvil     unix  -       -       y       -       1       anvil
scache    unix  -       -       y       -       1       scache
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent.  See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
#   lmtp    cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
#  mailbox_transport = lmtp:inet:localhost
#  virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus     unix  -       n       n       -       -       pipe
#  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
# Old example of delivery via Cyrus.
#
#old-cyrus unix  -       n       n       -       -       pipe
#  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix	-	n	n	-	2	pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
  ${nexthop} ${user}

之后再修改
/etc/postfix/main.cf
添加
content_filter =scan:[127.0.0.1]:10025
限制邮件最大大小为20M
message_size_limit = 20971520
由于我这里需要进行邮件中继所以修改了
relayhost = [127.0.0.1]:1250
设置relay_domains
relay_domains = hash:/etc/postfix/relay_domains
创建relay_domains运行命令
touch /etc/postfix/relay_domains
echo “test.com OK” > /etc/postfix/relay_domains
postmap /etc/postfix/relay_domains
如果不需要邮件中继请不要修改
最后看起来效果是这样的

# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = test.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost.localdomain, , localhost
relayhost = [127.0.0.1]:1250
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

message_size_limit = 20971520
relay_domains = hash:/etc/postfix/relay_domains
content_filter =scan:[127.0.0.1]:10025

最后service postfix restart即可

Ubuntu下使iptables规则重启继续生效

重启后iptable规则丢失,解决方法很简单,安装iptables-persistent即可
apt-get install iptables-persistent
也可以手动管理iptables规则
保存规则
Debian/Ubuntu: iptables-save > /etc/iptables/rules.v4
Debian/Ubuntu: ip6tables-save > /etc/iptables/rules.v6
恢复规则
Debian/Ubuntu: iptables-restore < /etc/iptables/rules.v4

2016/10/15 xmlrpc.php引起的网站瘫痪

说来装上wordpress也有一段时间了,一直没遇到过什么问题,不过今天突然发现blog挂掉了,访问主页显示Error establishing a database connection
粗略一看我想可能是mysql出问题了,于是果断的
service mysql restart
恢复正常后过了很短的时间又出现了同样的情况,所以果断去/var/log/mysql下看了error.log
日记中是这样记录的
161015 18:34:42 InnoDB: Using Linux native AIO
161015 18:34:42 InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137363456 bytes) failed; errno 12
161015 18:34:42 InnoDB: Completed initialization of buffer pool
161015 18:34:42 InnoDB: Fatal error: cannot allocate memory for the buffer pool
161015 18:34:42 [ERROR] Plugin ‘InnoDB’ init function returned error.
161015 18:34:42 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
161015 18:34:42 [ERROR] Unknown/unsupported storage engine: InnoDB
161015 18:34:42 [ERROR] Aborting
很显然是内存不够用,导致mysql挂掉了。毕竟blog用的服务器只有512M内存,可加swap的方案我觉得不太好,所以选择修改mysql设置。
Google了一下,修改mysql的配置/etc/mysql/my.cnf,在[mysqld]下面加上一行
innodb_buffer_pool_size =32M
之后service mysql restart,网站恢复正常。
网站正常后通过top我看到apache的负载很高,觉得肯定有问题,就去看了Wordfence的日志
日志显示有来自俄罗斯一个IP的大量访问xmlrpc.php文件
ip是191.96.249.53和 191.96.249.54
想必就是因为大量的访问导致此问题出现。搜索了一下xmlrpc.php,发现这个文件对我用处不大,并且存在一定的安全问题,所以我直接做了以下措施。
1、iptables禁止ip段
iptables -I INPUT -s 191.96.249.0/24 -j DROP
这样一来就缓解了访问情况
2、.htaccess禁止使用xmlrpc.php
修改网站.htaccess加上下面的
# protect xmlrpc

Order Deny,Allow
Deny from all

至此,网站问题解决。记录下来仅供参考