服务器LAMP安装配置、安全链接升级与企业邮箱相关

LNMP安装与配置

前期安装

  1. 更新 source list

# 这里我主要用的是linux - Debian的发行版,因此Reposity都是debian官方的。 # 尽量不要使用VPS服务商提供的Reposity,虽然更新可以省流量, # 但是有时候有的软件包可能被修改,或是功能被阉割,部署到生产服务器有时候会出现莫名其妙的问题 # 因此还是建议使用官方的Reposity ###### Debian Main Repos ###### deb http://ftp.us.debian.org/debian/ jessie main contrib non-free deb-src http://ftp.us.debian.org/debian/ jessie main contrib non-free ###### Debian Security Repos ###### deb http://security.debian.org/ jessie/updates main contrib non-free deb-src http://security.debian.org/ jessie/updates main contrib non-free ###### Debian Backports Repos ###### deb http://ftp.debian.org/debian jessie-backports main
  1. 安装mosh
  2. 安装git, fail2ban
  3. 安装curl
  4. 设置系统时间与字符编码UTF-8

@TODO 以上几个重要的软件包有时间再写

LAMP

1. 安装apache2

apt-get install apache2 
#由于我们需要使用clean url,因此需要激活apache的rewrite模块
a2enmod rewrite
  1. 安装mariadb – mysql
apt-get install mariadb-server mariadb-client
# 运行mysql_secure_installation 提升数据库初始化的安装性
mysql_secure_installation


apt-get install mariadb-server mariadb-client

#运行mysql_secure_installation 提升数据库初始化的安全性
mysql_secure_installation

#建立mysql用户
create user 'user'@'localhost' identified by 'passwd';

#配置数据库用户权限
GRANT ALL PRIVILEGES ON dbname.* TO 'user'@'localhost' WITH GRANT OPTION;
# 注意,这里和mysql可能有一点不同,必须加上 WITH GRANT OPTION,否则 用户添加的权限一直都是USAGE,USAGE不是实际的权限,因此是无效的,

# 修改数据库用户密码
SET PASSWORD FOR 'user'@'localhost' = PASSWORD('passwd');
# 这里和mysql也不一样,mysql修改用户密码使用的alter语句,这里也需要注意。

# 查看用户权限
SHOW GRANTS FOR 'username'@'localhost';

# 刷新权限
FLUSH PRIVILEGES;

3. 安装php5 (debian8目前stable repository中还没有加入php7)

apt-get install php5 php5-curl php5-gd php5-mysql php5-xmlrpc php5-json

2019年10约15日更新

PHP – FCGI 运行模式 + 切换底层服务器环境由 Apache 到 Nginx

Ngix 和 Apache 两者的性能差异是在架构层面上的。Nginx 运行在异步模式下,要比 Apache 的多线程要消耗更少的系统资源,且更快的响应请求,在我的阿里云小鸡上,对性能的节省就显得很重要。因此我打算将服务器环境切换为 Nginx .


# 1. 创建网站文件的存储目录 mkdir -p /var/www/html/example.com/public_html # 1. 创建相关的日志文件目录,以方便后期检查与维护 # 创建 NGINX 日志目录 mkdir -p /var/log/nginx # 创建 PHP 运行日志目录 mkdir -p /var/log/fpm-php # 2. 安装与配置 NGINX 及相关模块 apt-get install nginx fcgiwrap nginx-doc ssl-cert # 3. 查看 Nginx 状态 nginx -V # 3. 安装最新的 PHP 7.3, 由于 Debian 最新的 Testing 仓库已有 php7.3版本,因此这里我们直接从仓库安装 # 3.1 添加 Debian Testing 的数据源 echo -e '#Adding Testing Repository\n deb http://mirrors.aliyun.com/debian/ testing main' >> /etc/apt/sources.list # 3.2 安装 PHP 7.3 apt install php7.3-cli php7.3-fpm php7.3-common php7.3-json php7.3-readline

php7.0比php5.6版本有了大幅度的性能提升,而7.3比7.1还有20%的性能提升,因此我们需要使用 * debian stretch * 下 testing repositor 的最新7.3稳定版, 并且最终php运行模式为php-fpm。

3.2.1 设置默认的 PHP-FPM运行日志的输出目录

vi /etc/php/7.3/fpm/php-fpm.conf

将 24 行 error_log 设置修改为 以下位置

error_log = /var/log/fpm-php/php7.3-fpm.log

3.2.2 PHP 运行的默认设置

php.ini 使用系统的默认设置已经比较合适,这里就不做修改了

3.2.3 针对站点的pool设置

原则上每个站点对应一个php-fpm pool
pool配置文件目录/etc/php/7.3/fpm/pool.d/example.com.conf

[example.com]
prefix = /var/www/html/example.com
user = www-data
group = www-data
listen = /run/php/example.com.php.sock
listen.owner = www-data
listen.group = www-data
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
request_terminate_timeout = 300s
request_slowlog_timeout = 10s
chdir = /var/www/html/example.com/public_html
slowlog = /var/log/fpm-php/$pool.log.slow
php_flag[display_errors] = off
php_admin_value[display_errors]=0
php_admin_value[display_startup_errors]=0
php_admin_value[html_errors]=0
php_admin_value[define_syslog_variables]=0
php_admin_flag[file_uploads]=1
php_admin_flag[log_errors] = on
php_admin_value[log_errors]=1
php_admin_value[upload_tmp_dir]="/var/tmp"
php_admin_value[upload_max_filesize]="4M"
php_value[max_input_time]="120"
php_admin_value[max_input_time]=120
php_value[max_execution_time]="300"
php_admin_value[post_max_size]="4M"
php_value[session.gc_maxlifetime]=3600
php_admin_value[session.gc_probability]=1
php_admin_value[session.gc_divisor]=100
php_admin_value[error_log] = /var/log/fpm-php/example.com.log
php_admin_value[memory_limit] = 64M
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
php_admin_value[magic_quotes_gpc]=0
php_admin_value[register_globals]=0
php_admin_value[session.auto_start]=0
php_admin_value[mbstring.http_input]="pass"
php_admin_value[mbstring.http_output]="pass"
php_admin_value[mbstring.encoding_translation]=0
php_admin_value[expose_php]=0
php_admin_value[allow_url_fopen]=1
php_admin_value[safe_mode]=0
php_admin_value[cgi.fix_pathinfo]=1
php_admin_value[cgi.discard_path]=0

# 测试 example.com 的 fpm-php 配置文件是否正确
php-fpm7.3 -y /etc/php/7.3/fpm/pool.d/example.com.conf -t

````







4. 服务器安全性提升(安全性优化)

>@TODO这里暂时略过,有时间再写

5. 建立网站文件目录

> mkdir -p /var/www/domain.com/html/

6. 安装certbot证书签发程序

```bash

# 安装基本库
apt-get install gcc build-essential autoconf openssl

# 下载certbot最新版客户端
git clone https://github.com/certbot/certbot.git

# 解压后,运行目录下的certbot-auto安装certbot客户端
./cerbot/certbot-auto --install-only

# 使用最新版本的ACME2特性签发wildcard域名证书
# 注意wildcard证书只针对子域名,而根域名也需要签发证书,所以以下包含两个域名
./certbot-auto --server https://acme-v02.api.letsencrypt.org/directory -d *.domainexample.com -d domainexample.com --manual --preferred-challenges dns-01 certonly


# 在证书签发的过程中需要添加DNS TXT解析记录,已验证域名所有权,这里需要注意
# 签发成功后出现以下提示

 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/domainexample.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/domainexample.com/privkey.pem
   Your cert will expire on 2018-07-01. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"




# 如果因为一些原因而错误签发了证书,可以使用revoke命令撤销

# 如果你使用的是cert-only子命令获取的证书,这需要使用证书文件和私钥来撤销证书

./certbot-auto revoke --cert-path /etc/letsencrypt/archive/domainexample.com/cert1.pem --key-path  /etc/letsencrypt/archive/domainexample.com/privkey1.pem


2018年06月26日补充内容

由于LE的证书有效期只有三个月,因此不到三个月就要对证书进行renew,这就是免费证书所需要付出的代价,好在FE证书支持全站子域名的wildcard证书,三个月renew一次也就忍忍吧,不服和图方便的话,一年花个100刀买证书吧,毕竟钱花哪哪好。

由于目前我使用的就是wildcard证书,为wildcard证书需要连接acme-v02进行验证,并且wildcard目前只支持dns-01的授权方式,因此就不得不每次手动的manual来进行证书的renew。Renew的方法不是用certbot-auto的renew命令,因为是手动的,就需要使用certonly命令。后期考虑结合VPS服务商的DNS API来自动解决这个问题。

./certbot-auto \
--server https://acme-v02.api.letsencrypt.org/directory \
-d *.domainexample.com \
-d domainexample.com \
--manual \
--preferred-challenges dns-01 \
certonly


# 命令运行后会提示添加 TXT 文本格式的 DNS解析记录
# 注意由于添加证书的域名是根域名+wildcard子域名,因此需要添加2条DNS记录。
# 不然的话一直会验证不通过。

# 验证通过后顺利生成新的证书,并且/etc/letsencrypt/live/domainexample.com/目录下的证书指向软连接已经被成功更新。
# 重启或是reload apache服务,就会发现证书顺利的rewnew和更新了。

# service apache2 restart 或者 service apache2 reload

7. clone与修改apache的配置文件


# 443 安全连接与端口配置文件 # 注意事项 # 1. ssl的配置文件名和ssl的配置文件选项 # 根域名跳转到www <VirtualHost *:443> ServerName domainexample.com Redirect permanent / https://www.domainexample.com/ # 即使根域名全站跳转,也必须要明确的支出证书文件的路径,否则就会出现文章底部的错误。 SSLEngine on SSLCertificateFile /etc/letsencrypt/live/domainexample.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/domainexample.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/domainexample.com/fullchain.pem </VirtualHost> <VirtualHost *:443> ServerAdmin admin@domainexample.com ServerName www.domainexample.com DocumentRoot /var/www/html/domainexample.com/public_html/ ErrorLog /var/www/html/domainexample.com/logs/error.log CustomLog /var/www/html/domainexample.com/logs/access.log combined SSLEngine on SSLCertificateFile /etc/letsencrypt/live/domainexample.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/domainexample.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/domainexample.com/fullchain.pem </VirtualHost> # 2. 80端口的配置文件 # Redirect all 80 port traffic to 443 instead <VirtualHost *:80> ServerAdmin admin@domainexample.com ServerName domainexample.com ServerAlias www.domainexample.com DocumentRoot /var/www/html/domainexample.com/public_html/ ErrorLog /var/www/html/domainexample.com/logs/error.log CustomLog /var/www/html/domainexample.com/logs/access.log combined <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{SERVER_PORT} !^443$ RewriteRule (.*) https://%{SERVER_NAME}/$1 [R] </IfModule> </VirtualHost> # 上面的这种操作是一种heavy lift 如果需要跳转的链接成千上万,服务器就会有很重的负载 # 针对80端口的流量跳转 # 使用virtualhost的redirect属性设置比较优雅和高效 # 将所有根域名下的流量跳转到www <VirtualHost *:80> ServerName domainexample.com Redirect permanent / https://www.domainexample.com/ </VirtualHost> # 另外还需要在ServerName domainexample.com <VirtualHost *:80> ServerName www.domainexample.com # 由于domainexample.com已经被设置为一个独立的virtual host # 因此下方的ServerAlias设置项必须删除,这里我们直接注释掉 # ServerAlias domainexample.com ServerAdmin admin@domainexample.com DocumentRoot /var/www/html/domainexample.com/public_html # 将所有80端口流量重定向到443端口 Redirect permanent / https://www.domainexample.com/ DocumentRoot /var/www/html/domainexample.com/public_html/ ErrorLog /var/www/html/domainexample.com/logs/error.log CustomLog /var/www/html/domainexample.com/logs/access.log combined </VirtualHost> # 3. 激活Apache的ssl模块 a2enmod ssl # 这样与ssl相关的依赖模块也会被激活 # 之后重启服务器就可以愉快的享受ssl带来的安全性了。 service apache2 restart

# @TODO 以下有时间再补 # Apache配置与服务器性能优化 # 1. 提升安全性 # 2. 开启流量压缩 # 3. 并行下载,静态资源分离 # 4. 禁用不安全的HTTP协议

企业邮箱配置

企业邮箱的话,如果你的公司有营业执照和公章,则可以通过和阿里的OA平台 – 钉钉 签约,然后使用阿里云提供的免费企业邮箱服务,50个账户,每个账户5G容量,对于人数不多的公司完全够用了,一年可以省下将近2000块钱的费用。按照指引注册的话,快的话一天就可以审核通过使用了。

注意这里面也是有坑的。

  1. 你的域名无法直接绑定到钉钉提供的免费企业邮箱,必须按照钉钉的提示先申请一个 company-name.onaliyun.com的二级域名,然后企业邮箱的功能算是激活了。
  2. 进入钉钉手机端,钉邮 -> 【邮箱管理】-> 【绑定新域名】-> 添加自己公式的域名,然后后台会提示需要你添加DNS解析记录以验证域名所有权。
  3. 第二步是在域名的DNS解析页面上设置mx解析记录,解析到mxw.hichina.com和mxn.hichina.com,priority优先级分别是5和10。这两个服务器是阿里企业邮箱的DNS服务器。除此之外还要添加一个CNAME的DNS记录,主机为mail,地址为mail.mxhichina.com。由于MX记录同步比较慢,通常需要1-2个小时才会生效。
  4. 验证通过后自己的域名就会现在在邮箱的管理页面中,在钉钉手机端后台选中自己的域名设置为默认,这样所有人的企业邮箱都会变成自己域名的后缀。
  5. 走完这一步,就可以在钉钉的通讯录中邀请公司的同事加入组织,并为他们配置企业邮箱账户。
  6. 然而即使你为每个人都配置完企业邮箱了,这个时候你仍然没有办法使用客户端来收信。什么?你就是为了骗企业邮箱和邮件客户端收信这个来的?别急。即使你用foxmail添加了邮箱的地址,你输入了钉钉的账户密码,IMAP/SMTP端口什么的你都配置正确,你还是收不到信。那么怎么办?你需要在钉钉的后台 【通讯录】->【邮箱账户管理】->【个人邮箱】->【重设密码】为每个邮箱账户重设密码,然后每个人都登陆一下阿里企业邮箱网页版 https://qiye.aliyun.com 修改密码。因为企业邮箱的登录密码,不是钉钉账户的密码。所以用钉钉账户的密码是没有办法在邮箱客户端登陆邮件服务器的。改完密码之后使用新密码配置邮件客户端,一切都正常了。而搞笑的是,打电话给钉钉的客服,客户告诉我免费账户不支持IMAP客户端收信,嗯嗯,你说的对,但是我不信。

2018年7月4日补充更新

当你打开网站的https页面出现错误SSL_ERROR_RX_RECORD_TOO_LONG(firefox)或是发送的响应无效 ERR_SSL_PROTOCOL_ERROR (Chrome)时, 且测试 http://www.domain.com:443 可以访问,说明http运行在443端口。

且你确信证书的签发没有问题,且netstat -npl 列出的端口也是开放的,因此出问题的就是apache2的配置文件,准确的说应该是site-available目录下的配置文件有问题。

注意无论是哪个server name下来的站点配置文件,即使全站跳转,配置文件也必须明确的指除证书文件的具体路径,否则就会出现上面的问题。解决办法就是在每一个virtualhost *:443 配置项下都必须明确指出SSL证书相关文件的路径。

配置项的问题解决之后,service apache2 reload 一切就正常了。