持续集成开发:Jenkins自动打包实践

对于Jenkins的使用,本人是小白一个,本人实践就是按照大神的文章自己做了一次尝试。本文主要说明一下在实践中遇到的坑。

参考文章:

http://www.jianshu.com/p/41ecb06ae95f

1、打包的时候找不到证书

之前安装Jenkins使用的是官网的.pkg。这样的话会安装到 用户/共享目录下。这样就会造成打包的时候找不到证书。

解决方法:使用命令行安装。cd /Library 可在该路径执行相关命令。

参考文章http://blog.csdn.net/jiisd/article/details/60878398

2、在Jenkins中配置,在Jenkins的证书管理中添加SSH

未分类

电脑中ssh的生成及查看方式:前往cd /Users/wangjiajia/.ssh 打开id_rsa.pub即可

未分类

当所有配置没有问题的情况下:进行构建的时候可能会出现 times out 的问题。这时候在Jenkins中设置一下超时时间就好

未分类

参考文章:

https://linmi.cc/901

https://stackoverflow.com/questions/36017253/jenkins-git-fetch-timeout

3、本地脚本存放位置

/Users/用户名/.jenkins/workspace/具体的项目的文件夹

在配置好git仓库的地址之后,即可进行一次构建。这时候如果没有错误,就可将git仓库的代码拉取到本地:/Users/用户名/.jenkins/workspace/

未分类

这时可将脚本文件及plist文件拷贝进该目录

参考文章:

http://www.jianshu.com/p/5d59966eaecc?from=timeline

该文章提供的脚本有输入功能,但是Jenkins自动打包的时候并没有让进行输入,因此,可以改变脚本配置实现为不同配置打包。

4、打包过程中,会出现找不到target的情况

未分类

未分类

修改权限,上传代码到远端,重新构建即可。

实践中与参考文章配置不同的地方:

我的Jenkins本没有配置着这些信息:

上传keychain及provisioning profile

未分类

未分类

未分类

构建环境配置

未分类

最终Jenkins配置样例

general

未分类

源码管理

未分类

构建

未分类

配置描述

未分类

jenkins实现PHP项目持续集成部署

安装jenkins相关依赖

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
yum install jenkins
yum install Java
yum install java-1.8.0-openjdk
yum install PHP
yum install php-devel
yum install php-pear
yum install re2c
yum install php-pear-phing

jenkins配置和启动

service jenkins start

输入localhost:8080即可访问。

插件安装

  • 系统管理-插件设置
  • 安装以下插件
  • Phing(php构建工具)
  • Publish Over SSH Plugin(通过ssh发布代码)

配置SSH免登录

假设有两台服务器。A为发布机,即jenkins所在机器。B为应用服务器,即运行PHP的服务器。

首先在A服务器生成公私钥。

ssh-keygen -t rsa

这时.ssh目录下会生成私钥和公钥的键值对id_rsa,id_rsa.pub

将id_rsa.pub公钥复制到B服务器上,并重命名为authorized_keys。

scp ~/.ssh/ras.pub root@B:/root/.ssh/authorized_keys

这时候ssh到B服务器则无需登录密码。

ssh root@B

注:若生成RSA密码的时候设置了ssh key,SSH到B服务器的时候还需要输入相应ssh key。

配置Publish Over SSH Plugin

系统管理—系统设置

未分类

  • Jenkins SSH Key:生成rsa的时候设置的ssh key,若没有设置则留空。
  • Key:填上A服务器私钥的内容。默认路径 ~/.ssh/id_rsa
  • Hosename:填上B服务器的IP
  • username:填上B服务器的帐号

配置phing build.xml

进入当前job的项目目录

cd /var/lib/jenkins/workspace/Git

未分类

build.xml文件内容如下

<?xml version="1.0" encoding="UTF-8"?>
<project name="api" default="build">
        <target name="build" depends="make_runtime,check,tar"/>
        <property name="version-m"  value="1.1" />
        <property name="version"    value="1.1.0" />
        <property name="stability"  value="stable" />
        <property name="releasenotes" value="" />
        <property name="tarfile"     value="${phing.project.name}.${buildnumber}.${buildid}.tar.gz" />
        <property name="pkgfile"     value="${phing.project.name}.${version}.tgz" />
        <property name="distfile"    value="dist/${tarfile}" />
        <property name="tests.dir" value="test" />
        <fileset id="api.tar.gz" dir=".">
            <include name="test/**"/>
            <include name="*.php"/>
            <include name="*.xml"/>
        </fileset>
        <target name="make_runtime">
                <mkdir dir="${project.basedir}/Runtime" />
                <mkdir dir="${project.basedir}/build/logs" />
                <mkdir dir="${project.basedir}/build/pdepend" />
                <mkdir dir="${project.basedir}/build/code-browser" />
        </target>

        <target name="check" description="Check variables" >
            <fail unless="version" message="Version not defined!" />
            <fail unless="buildnumber" message="buildnumber not defined!" />
            <fail unless="buildid" message="buildid not defined!" />
            <delete dir="dist" failonerror="false" />
            <mkdir dir="dist" />
        </target>

        <target name="tar" depends="check" description="Create tar file for release">
            <echo msg="Creating distribution tar for ${phing.project.name} ${version}"/>
            <delete file="${distfile}" failonerror="false"/>
            <tar destfile="${distfile}" compression="gzip">
                <fileset refid="api.tar.gz"/>
            </tar>
        </target>
</project>

这里我们只做简单发布,没有加入php-unit等插件。

开始构建项目

新建—输入项目名称,选择构建自由风格的软件项目—下一步

配置源码管理

这里我们用的是git

未分类

增加构建步骤,选择Invoke Phing targets,再新增一个构建步骤,选择Send files or execute commands over SSH

未分类

Phing targets配置如下

未分类

Send files or execute commands over SSH 配置如下

未分类

Source files:dist/api.${BUILD_NUMBER}.${BUILD_ID}.tar.gz
Remove prefix:dist/
Remote directory: /home/data/
Exec command:
mkdir -p /home/data/
mkdir-p /home/www/
cd /home/data/
tar -zxf api.${BUILD_NUMBER}.${BUILD_ID}.tar.gz -C /home/www/
  • /home/data/ 为B服务器接收打包文件的目录
  • /home/www/ 为B服务器PHP项目运行的目录

保存即可。

接下来进入项目–立即构建,完成后我们进入B服务器。

cd /home/data

未分类

至此已经大功搞成了。

一步步手工搭建etcd集群

目标

搭建一套三节点的 etcd 高可用集群

资源准备

  • 准备三台 Linux 服务器
192.168.9.1

192.168.9.2

192.168.9.3
  • 下载 etcd-v3.2.5

  • etcd:由于 raft 算法的特性,集群的节点数必须是奇数

服务器初始化

  • 三台服务器分别创建 etcd 用户并指定 gid 为:etcd

etcd 集群配置

  • 分别在三台服务器创建 conf、data、bin 目录:
etcd@XXXX$ mkdir -p /home/etcd/{conf,data,bin}
  • 将 etcd-v3.2.5-linux-amd64.tar.gz 分别上传至三台服务器中,解压后将 etcdctl、etcd 复制到 /home/etcd/bin 目录下,并将 /home/etcd/bin 目录配置到系统环境变量下

  • 三台服务器分别编辑 systemd 启动文件:

使用 root 用户编辑: vi /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/home/etcd/data
EnvironmentFile=-/home/etcd/conf/etcd.conf
User=etcd
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /home/etcd/bin/etcd 
  --name ${ETCD_NAME} 
  --initial-advertise-peer-urls ${ETCD_INITIAL_ADVERTISE_PEER_URLS} 
  --listen-peer-urls ${ETCD_LISTEN_PEER_URLS} 
  --listen-client-urls ${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 
  --advertise-client-urls ${ETCD_ADVERTISE_CLIENT_URLS} 
  --initial-cluster-token ${ETCD_INITIAL_CLUSTER_TOKEN} 
  --initial-cluster ${ETCD_CLUSTER_ADDRESS} 
  --initial-cluster-state new 
  --data-dir=${ETCD_DATA_DIR}"
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
  • 通过 etcd 用户编辑 etcd 的启动参数文件:
vi /home/etcd/conf/etcd.conf
  • 规划三个节点 etcd name 分别为:etcd1、etcd2、etcd3

  • 下列配置文件内容中包含中文处需要根据当前服务器实际信息进行修改,ETCD_CLUSTER_ADDRESS 的值也要根据自己实际的 IP 就行修改,切记请勿直接 copy 后就立即使用

# [member]
ETCD_NAME=当前节点的etcd name,例如:etcd1
ETCD_DATA_DIR="/home/etcd/data"
ETCD_LISTEN_PEER_URLS="http://当前服务器IP:2380"
ETCD_LISTEN_CLIENT_URLS="http://当前服务器IP:2379"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""

#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://当前服务器IP:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://当前服务器IP:2379"
ETCD_CLUSTER_ADDRESS="etcd1=http://192.168.9.1:2380,etcd2=http://192.168.9.2:2380,etcd3=http://192.168.9.3:2380"

#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
#ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_STRICT_RECONFIG_CHECK="false"
#ETCD_AUTO_COMPACTION_RETENTIO:N="0"
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
  • 通过 systemctl 启动 etcd,分别在三台服务器上通过 root 组用户执行:
systemctl daemon-reload
systemctl start etcd
  • 集群健康状态检测

任意一台服务器上通过 etcd 用户执行:etcdctl cluster-health
如果三个节点状态都是 is healthy,证明 etcd 集群搭建完毕。

怎么利用wget下载文件并保存到指定目录

资源下载的尴尬时刻

有时候人在天朝确实好难下载到墙外的资源(抓头发),好比说我今天忍不住买了一个付费插件,挂了V P N下载,愣是一直卡在0.1MB/6MB,更要命的是有时卡在95%/100%,然而开google网页秒开,无解……

未分类

郁闷了几分钟,想说可不可以通过服务器(前提你得有个服务器)下载到资源,再把资源用FTP下载到本地电脑,嗯可行,百度下,该文详述了服务器指令wget的详细用法(http://java-er.com/blog/wget-useage-x/),我只需用下面这个,记录下:

wget是Linux上一个非常不错的下载指令,一般来说,要使用wget下载档案,只需要打以下的指令:

wget 网址

而要让档案自动储存到指令的目录下,则需要借用-P这个参数,可以使用以下的指令

wget -P 目录 网址

举例来说,如果你要放到/root底下,你可以打下列的指令:

wget -P /root 网址

利用wget下载文件并保存到指定目录

炒鸡简单,套用“wget -P 目录 网址”指令齐全如下:

wget -P /root https://yoast-mercury.s3.amazonaws.com/uploads/edd/2017/07/wordpress-seo-premium-5.0.2.zip

指令核对清楚后,点击enter执行,就可以看到代码行在跑了,如下文和下图所示:

[root@xxxxxx ~]# wget -P /root https://yoast-mercury.s3.amazonaws.com/uploads/edd/2017/07/wordpress-seo-premium-5.0.2.zip
--2017-07-24 11:31:44-- https://yoast-mercury.s3.amazonaws.com/uploads/edd/2017/07/wordpress-seo-premium-5.0.2.zip
Resolving yoast-mercury.s3.amazonaws.com... 52.216.227.120
Connecting to yoast-mercury.s3.amazonaws.com|52.216.227.120|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6744136 (6.4M) [application/zip]
Saving to: ?.root/wordpress-seo-premium-5.0.2.zip.1?

100%[===============================================================>] 6,744,136 285K/s in 59s (平均速度285K每秒,59秒下载完毕!)

2017-07-24 11:32:43 (112 KB/s) - ?.root/wordpress-seo-premium-5.0.2.zip.1?.saved [6744136/6744136]

未分类

打开FTP工具,可以看到资源已经下载到指定的服务器目录底下了!右击传输到自己的本地电脑即可:)

终于拿到了付费插件,心情是激动的:

未分类

如何知道资源的下载网址?

一般用chrome浏览器,下载失败后会提示,举个例子,如图:

未分类

  • AhrefsTop-24-Jul-27831f24679b5143712800002a891b96.csv 已取消
  • https://ahrefs.com/download/2017-07-24/csv/AhrefsTop-24-Jul-27831f24679b5143 (这个网址就是下载地址啦,但是它最后的文件名不完整,把第一行的文件名代入即可啦)

补全后,完整的下载地址就是这样子啦:https://ahrefs.com/download/2017-07-24/csv/AhrefsTop-24-Jul-27831f24679b5143712800002a891b96.csv

  • 资料大小;25M
  • 下载速度:3.02M每秒
  • 下载时间:7.4秒
[root@xxxxxxxxxx ~]# wget -P /root https://ahrefs.com/download/2017-07-24/csv/AhrefsTop-24-Jul-27831f24679b5143712800002a891b96.csv
--2017-07-24 11:05:30-- https://ahrefs.com/download/2017-07-24/csv/AhrefsTop-24-Jul-27831f24679b5143712800002a891b96.csv
Resolving ahrefs.com... 151.80.39.61
Connecting to ahrefs.com|151.80.39.61|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 26285637 (25M) [text/csv]
Saving to: ?.root/AhrefsTop-24-Jul-27831f24679b5143712800002a891b96.csv?

100%[=========================================================>] 26,285,637 3.02M/s in 7.4s

2017-07-24 11:05:38 (3.40 MB/s) - ?.root/AhrefsTop-24-Jul-27831f24679b5143712800002a891b96.csv?.saved [26285637/26285637]

以后可以愉快地玩耍了。

设置curl和wget使用http https代理

Linux Shell 提供两个非常实用的命令来爬取网页,它们分别是 curl 和 wget

curl 和 wget 使用代理

  • curl 支持 http、https、socks4、socks5

  • wget 支持 http、https

代理示例:

#!/bin/bash
#
# curl 支持 http、https、socks4、socks5
# wget 支持 http、https
#


# http代理格式         http_proxy=http://IP:Port
# https代理格式         https_proxy=http://IP:Port

{'http': 'http://120.77.176.179:8888'}
curl -m 30 --retry 3 -x http://120.77.176.179:8888 http://proxy.mimvp.com/exist.php                    # http_proxy
wget -T 30 --tries 3 -e "http_proxy=http://120.77.176.179:8888" http://proxy.mimvp.com/exist.php          # http_proxy

{'https': 'http://46.105.214.133:3128'}
curl -m 30 --retry 3 --proxy-insecure -x http://46.105.214.133:3128 -k https://proxy.mimvp.com/exist.php                    # https_proxy
wget -T 30 --tries 3 --no-check-certificate -e "https_proxy=http://46.105.214.133:3128" https://proxy.mimvp.com/exist.php    # https_proxy


# curl  支持socks
{'socks4': '101.255.17.145:1080'}
curl -m 30 --retry 3 --socks4 101.255.17.145:1080 http://proxy.mimvp.com/exist.php

{'socks5': '82.164.233.227:45454'}
curl -m 30 --retry 3 --socks5 82.164.233.227:45454 http://proxy.mimvp.com/exist.php


# wget 不支持socks

wget 配置文件设置代理

vim ~/.wgetrc

http_proxy=http://120.77.176.179:8888:8080
https_proxy=http://12.7.17.17:8888:8080
use_proxy = on
wait = 30

wget -T 30 --tries 3 http://proxy.mimvp.com

Shell 设置临时局部代理

# proxy no auth
export http_proxy=http://120.77.176.179:8888:8080
export https_proxy=http://12.7.17.17:8888:8080

# proxy auth
export http_proxy=http://username:[email protected]:8888:8080
export https_proxy=http://username:[email protected]:8888:8080


# 取消设置
unset http_proxy
unset https_proxy

Shell 设置系统全局代理

# 修改 /etc/profile,保存并重启服务器
sudo vim /etc/profile        # 所有人有效
或
sudo vim ~/.bashrc        # 所有人有效
或
vim ~/.bash_profile        # 个人有效


# proxy no auth
export http_proxy=http://120.77.176.179:8888:8080
export https_proxy=http://12.7.17.17:8888:8080

# proxy auth
export http_proxy=http://username:[email protected]:8888:8080
export https_proxy=http://username:[email protected]:8888:8080

source /etc/profile
或
source ~/.bashrc
或
source ~/.bash_profile


sudo reboot

CentOS 6安装Sendmail Dovecot Squirrelmail邮件系统

本文记录在本地虚拟机CentOS6上搭建Sendmail + Dovecot + Squirrelmail 的Webmail环境的过程,仅仅是本地局域网的环境测试,不配置DNS, 也没有安全认证,Squirrelmail 版本squirrelmail-webmail-1.4.22。

前言

关于CentOS系统的安装,这里便不做介绍了,大家可以在网上找到很多相关的资料参考。如果已经对下面的命令熟悉的朋友,请直接跳到下一步…

现简单介绍一下一些基本命令的使用:

1、查看系统发行版本

[lz@localhost ~]$ cat /etc/issue
CentOS release 6.9 (Final)
Kernel r on an m

2、查看内核版本

[lz@localhost ~]$ uname -a
Linux localhost.localdomain 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

3、获取系统权限

[lz@localhost ~]$ su root      
Password:             【输入lz的密码】
[root@localhost lz]# 

4、让用户能获取root权限

[root@localhost lz]# vim /etc/sudoers

未分类

按esc键,输入:wq! 保存文件,退出,这样lz就用使用sudo命令获取root权限了。来,试试看。

[root@localhost lz]# exit
exit
[lz@localhost ~]$ sudo -i     【获取root权限】
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.
[sudo] password for lz: 
[root@localhost ~]# 

5、修改主机名和hosts文件

[root@mail ~]# cat /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=mail.squirrelmail.com
[root@mail ~]# cat /etc/hosts
127.0.0.1 mail.squirrelmail.com localhost.localdomain
127.0.0.1 squirrelmail.com  localhost.localdomain
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6

重启一下系统,命令提示符前面的就会变成如上所示。

6、更新系统

[root@mail ~]# yum update

这个过程可能需要比较长的时间,耐心等待系统更新完成。

一、Sendmail安装和配置

下面记录Sendmail的安装过程,重要的步骤会给出命令行输出结果。首先,我们需要安装一些依赖包,CentOS系统使用yum来安装,跟Debian/Ubuntu的apt-get 类似可以很方便的安装一些软件。press y

[root@mail mail]# yum install m4 telnet mailx
Loaded plugins: fastestmirror, refresh-packagekit
Setting up Install Process
Loading mirror speeds from cached hostfile
* base: centos.ustc.edu.cn
* extras: centos.ustc.edu.cn
* updates: centos.ustc.edu.cn
Package m4-1.4.13-5.el6.x86_64 already installed and latest version
Package 1:telnet-0.17-48.el6.x86_64 already installed and latest version
Package mailx-12.4-8.el6_6.x86_64 already installed and latest version
Nothing to do

1、Sendmail安装

[root@mail mail]# yum install sendmail sendmail-cf
Loaded plugins: fastestmirror, refresh-packagekit
Setting up Install Process
Loading mirror speeds from cached hostfile
* base: centos.ustc.edu.cn
* extras: centos.ustc.edu.cn
* updates: centos.ustc.edu.cn
Package sendmail-8.14.4-9.el6_8.1.x86_64 already installed and latest version
Package sendmail-cf-8.14.4-9.el6_8.1.noarch already installed and latest version
Nothing to do

我这已经安装好了,仅演示安装过程,在软件的安装过程中,会提示输入[y/N] : y , 当然输入y了

2、Sendmail配置

Sendmail的配置文件默认是在/etc/mail目录下的:

[root@mail mail]# ls /etc/mail
access     aliasesdb-stamp  domaintable.db  local-host-names  mailertable.db  Makefile     sendmail.cf.bak  submit.cf  trusted-users  virtusertable.db
access.db  domaintable      helpfile        mailertable       make            sendmail.cf  sendmail.mc      submit.mc  virtusertable

默认监听的是本地接口地址: 127.0.0.1:25, 我们可以通过命令查看

[root@mail mail]# ps -ef | grep -v grep | grep -i sendmail
root      29409      1  0 14:52 ?        00:00:00 sendmail: accepting connections
smmsp     29419      1  0 14:52 ?        00:00:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
[root@mail mail]# netstat -an | grep :25 | grep tcp
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN

如果要让Sendmail监听本机的所有接口地址,可以修改sendmail.mc文件, 如果默认监听的是0.0.0.0:25,则可以跳过下面这步。

[root@mail mail]# vim /etc/mail/sendmail.mc
大概在116行, 将如下内容注释掉, 在行首添加dnl
From:
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

To:
dnl # DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

重启一下Sendmail,再查看:

[root@mail ~]# service sendmail restart
Shutting down sm-client:                                   [  OK  ]
Shutting down sendmail:                                    [  OK  ]
Starting sendmail:                                         [  OK  ]
Starting sm-client:                                        [  OK  ]
[root@mail ~]# netstat -an | grep :25 | grep tcp
tcp        0      0 0.0.0.0:25                  0.0.0.0:*                   LISTEN 

下面将使用m4这个工具来创建sendmail.cf这个文件

[root@mail ~]# m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf

在local-host-names增加域名项,表示的是可以用来发送/接收邮件的域名。

[root@mail ~]# cat /etc/mail/local-host-names 
# local-host-names - include all aliases for your machine here.
squirrelmail.com
mail.squirrelmail.com

重启Sendmail,设置开机启动。

[root@mail ~]# service sendmail restart
Shutting down sm-client:                                   [  OK  ]
Shutting down sendmail:                                    [  OK  ]
Starting sendmail:                                         [  OK  ]
Starting sm-client:                                        [  OK  ]
[root@mail ~]# chkconfig sendmail on      【开机启动】

3、Sendmail发送邮件测试: mail命令测试

首先创建两个测试的账户: 使用useradd命令添加两个用户user1和user2、然后用passwd命令更改密码、再将用户添加到mail组。

[root@mail ~]# useradd user1      【添加用户】
[root@mail ~]# useradd user2
[root@mail ~]# passwd user1       【修改密码】
Changing password for user user1.
New password: 
BAD PASSWORD: it does not contain enough DIFFERENT characters
BAD PASSWORD: is too simple
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@mail ~]# passwd user2       【修改密码】
Changing password for user user2.
New password: 
BAD PASSWORD: it does not contain enough DIFFERENT characters
BAD PASSWORD: is too simple
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@mail ~]# gpasswd -a user1 mail    【添加用户到mail组】
Adding user user1 to group mail
[root@mail ~]# gpasswd -a user2 mail
Adding user user2 to group mail

用其中一个账户登陆,给另一个用户发送邮件

[root@mail ~]# su user1      【切换用户user1】      
[user1@mail root]$ mail -s "hello user2" user2      [发送邮件:mail -s "主题内容" "收信人"]
This is a test mail from user1.               【邮件正文】               
.
EOT
[user1@mail root]$ exit
exit
[root@mail ~]# cat /var/mail/user2             【查看邮件】
From [email protected]  Wed Aug  9 17:18:16 2017
Return-Path: <[email protected]>
Received: from mail.squirrelmail.com (mail.squirrelmail.com [127.0.0.1])
    by mail.squirrelmail.com (8.14.4/8.14.4) with ESMTP id v799IFCn003225
    for <[email protected]>; Wed, 9 Aug 2017 17:18:16 +0800
Received: (from user1@localhost)
    by mail.squirrelmail.com (8.14.4/8.14.4/Submit) id v799IFjw003224
    for user2; Wed, 9 Aug 2017 17:18:15 +0800
From: [email protected]
Message-Id: <[email protected]>
Date: Wed, 09 Aug 2017 17:18:15 +0800
To: [email protected]
Subject: hello user2
User-Agent: Heirloom mailx 12.4 7/29/08
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

This is a test mail from user1.

可以看到,上面的邮件发送成功。

[说明] 使用mail命令发送邮件, “-s”后面接邮件主题,然后是接收邮件的账户,直接使用用户名即可,在本域测试。然后输入邮件正文,最后用’.’ ,表示邮件正文结束。

4、Sendmail发送邮件测试: telnet方式测试

未分类

5、防火墙设置

需要设置防火墙允许本机25号端口的数据通过:

[root@starnight mail]# iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT

保存防火墙设置,并重启:

[root@starnight mail]# service iptables save      【保存设置】
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]
[root@starnight mail]# service iptables restart    【重启防火墙】
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]
iptables: Applying firewall rules:                         [  OK  ]
[root@starnight mail]# service iptables stop      【关闭,我比较暴力】
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]
[root@starnight mail]#  

到这里,Sendmail的配置就完成了。成功!

二、Dovecot 安装配置

需要先安装一些依赖包:

[root@mail ~]# yum install telnet mailx mutt

1、Dovecot安装

[root@mail ~]# yum install dovecot

2、Dovecot配置

默认情况下,Dovecot的配置文件在/etc/dovecot/下

[root@mail ~]# ls /etc/dovecot/
conf.d  dovecot.conf

修改配置文件/etc/dovecot/dovecot.conf:

[root@mail ~]# vim /etc/dovecot/dovecot.conf

去掉protocols的注释, 即去掉’#’

未分类

打开配置文件/etc/dovecot/conf.d/10-mail.conf:

[root@mail ~]# vim /etc/dovecot/conf.d/10-mail.conf

设置:mail_location = mbox:~/mail:INBOX=/var/mail/%u

未分类

启动和查看Dovecot 服务:

[root@mail ~]# service dovecot start
Starting Dovecot Imap:                                     [  OK  ]
[root@mail ~]# ps -ef | grep -v grep | grep -i dovecot
root       3556      1  0 17:42 ?        00:00:00 /usr/sbin/dovecot
dovecot    3558   3556  0 17:42 ?        00:00:00 dovecot/anvil
root       3559   3556  0 17:42 ?        00:00:00 dovecot/log
root       3561   3556  0 17:42 ?        00:00:00 dovecot/config
[root@mail ~]# netstat -planet | grep -i dove
tcp        0      0 0.0.0.0:993                 0.0.0.0:*                   LISTEN      0          21510      3556/dovecot        
tcp        0      0 0.0.0.0:995                 0.0.0.0:*                   LISTEN      0          21502      3556/dovecot        
tcp        0      0 0.0.0.0:110                 0.0.0.0:*                   LISTEN      0          21500      3556/dovecot        
tcp        0      0 0.0.0.0:143                 0.0.0.0:*                   LISTEN      0          21508      3556/dovecot        
tcp        0      0 :::993                      :::*                        LISTEN      0          21511      3556/dovecot        
tcp        0      0 :::995                      :::*                        LISTEN      0          21503      3556/dovecot        
tcp        0      0 :::110                      :::*                        LISTEN      0          21501      3556/dovecot        
tcp        0      0 :::143                      :::*                        LISTEN      0          21509      3556/dovecot 

3、Dovecot接收邮件测试: mutt

之前在测试Sendmail的时候,用user1这个账户向user2发送了一封邮件,通过查看本地文件进行验证。

[root@mail ~]# mutt -f imap://user2:123456@localhost              【用户user2  密码:123456】

第一次使用在底部会有提示,按照提示进行即可:

未分类
yes

未分类
a

accept 之后,会出现如下邮件列表,

未分类

按回车键即可查看邮件:

未分类

【注】如果新建的用户user1或user2没有加入到mail用户组,通过这种方式查看邮件就会出错。

4、Dovecot接收邮件测试: telnet方式测试

未分类

到这里,Dovecot的配置就完成了。成功!

三、Squirrelmail安装

1、配置Web环境

CentOS Apache2默认应该是安装了的,名称为httpd,如果没有安装可以采用如下命令进行安装

安装:

[root@mail html]# yum install httpd

启动、停止、重启等命令:

[root@mail html]# service httpd start
Starting httpd:                                            [  OK  ]
[root@mail html]# service httpd stop
Stopping httpd:                                            [  OK  ]
[root@mail html]# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

此刻访问虚拟机ip地址,应该就能正常访问了

未分类

2、安装PHP

安装方法也很简单:

[root@mail html]# yum install php

测试: 在web根目录:/var/www/html, 编写如下文件info.php

[root@mail html]# pwd
/var/www/html
[root@mail html]# cat info.php 
<?php
phpinfo();
?>

浏览器访问:http://192.168.1.103/info.php

未分类

3、下载和配置Squirrelmail

下载:

切换到web根目录:使用如下命令下载

[root@mail html]# wget https://nchc.dl.sourceforge.net/project/squirrelmail/stable/1.4.22/squirrelmail-webmail-1.4.22.tar.gz

未分类

解压:

[root@mail html]# tar -zxvf squirrelmail-webmail-1.4.22.tar.gz 
[root@mail html]# ls
info.php  squirrelmail-webmail-1.4.22  squirrelmail-webmail-1.4.22.tar.gz
[root@mail html]# mv squirrelmail-webmail-1.4.22 squirrelmail            【重命名为squirrelmail】
[root@mail html]# ls
info.php  squirrelmail  squirrelmail-webmail-1.4.22.tar.gz
[root@mail html]# cd squirrelmail
[root@mail squirrelmail]# ls
class  config  configure  contrib  data  doc  functions  help  images  include  index.php  locale  plugins  po  README  src  themes
[root@mail squirrelmail]# cd config
[root@mail config]# ls
config_default.php  config_local.php  conf.pl  index.php

配置:

运行配置文件:

[root@mail config]# pwd
/var/www/html/squirrelmail/config
[root@mail config]# ls
config_default.php  config_local.php  conf.pl  index.php
[root@mail config]# ./conf.pl         【运行配置文件】

配置项如下:

未分类

修改一下域名:可以根据自己的需求进行相应的修改。

[2].  Server Settings  => [1].  Domain  => 输入:mail.squirrelmail.com  => 输入:S  [保存数据] =>  输入:R [返回上一级]  => Q [退出]

4、测试和修改

浏览器访问:http://192.168.1.103/squirrelmail/src/configtest.php

未分类

看到上面出现两个错误,我们可以尝试解决一下:

  • PHP short_open_tag = off 需要设置为On

[root@mail html]# vim /etc/php.ini

未分类

  • 在填加两个文件夹data和attach,并赋予写权限
[root@mail ~]# cd /var/local/
[root@mail local]# ls
[root@mail local]# mkdir squirrelmail
[root@mail local]# cd squirrelmail/
[root@mail squirrelmail]# mkdir data
[root@mail squirrelmail]# mkdir attach
[root@mail squirrelmail]# chmod a+w data/
[root@mail squirrelmail]# chmod a+w attach/
[root@mail squirrelmail]# ls -l
total 8
drwxrwxrwx 2 root root 4096 Aug  9 21:39 attach
drwxrwxrwx 2 root root 4096 Aug  9 21:39 data 

重启一下Web服务器: httpd

[root@mail squirrelmail]# service httpd restart

再次访问正常:

未分类

5、登陆Squirrelmail 和邮件发送、接收测试

现在可以访问: http://192.168.1.103/squirrelmail/src/login.php

未分类

用之前新建的账户名: user1/user2 : 123456 登陆, 用user2登陆看看,可以发现已经有一封之前发送的邮件了

未分类

下面我们在Webmail中发送邮件试试:user2 发送给 user1

未分类

再用user1登陆看看, 可以看到我们刚才发送的测试邮件…

未分类

至此,我们在CentOS6 上安装 Sendmail + Dovecot + Squirrelmail 圆满成功。

【注】不得不提的是,这只是个局域网的Webmail的测试环境,如果要实际使用的话,还必须搭建一个DNS服务器,还有跟邮件服务器配套的相关垃圾邮件过滤,认证之类的。

ngx_http_mirror_module- nginx流量镜像模块用法

Nginx 1.13.4版本新增了ngx_http_mirror_module模块。

ngx_http_mirror_module模块适用于这样一种场景,可以把真实请求引流到测试环境。

配置示例

location / {

    mirror /mirror;

    proxy_pass http://backend;

}


location /mirror {

    internal;

    proxy_pass http://test_backend$request_uri;

}

配置两组后台服务器,http://backend指向生产服务器, http://test_backend指向测试服务器。

用户访问生产服务器的同时,请求会被nginx复制发送给测试服务器,需要注意的一点是mirror不会输出http返回内容。

Nginx流量拷贝ngx_http_mirror_module模块配置及分析

一、背景

最近nginx官网公布了nginx1.13.4最新的ngx_http_mirror_module模块,利用mirror模块,业务可以将线上实时访问流量拷贝至其他环境,基于这些流量可以做版本发布前的预先验证,进行流量放大后的压测等等。本着兴趣笔者调研了其实现原理和使用方式,通过demo的形式展示给读者,希望能解决大家在使用过程中遇到的问题。

二、mirror模块配置

mirror模块配置分为两部分,源地址和镜像地址配置,配置位置可以为nginx配置文件的http, server, location上下文,配置示例为:

# original配置
location / {
    mirror /mirror;
    mirror_request_body off;
    proxy_pass http://127.0.0.1:9502;
}

# mirror配置
location /mirror {
    internal;
    proxy_pass http://127.0.0.1:8081$request_uri;
    proxy_set_header X-Original-URI $request_uri;
}

1、original配置

  • location /指定了源uri为/

  • mirror /mirror指定镜像uri为/mirror

  • mirror_request_body off | on 指定是否镜像请求body部分,此选项与proxy_request_buffering、fastcgi_request_buffering、scgi_request_buffering和 uwsgi_request_buffering冲突,一旦开启mirror_request_body为on,则请求自动缓存;

  • proxy_pass 指定上游server的地址

2、mirror配置

  • internal 指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)

  • proxy_pass 指定上游server的地址

  • proxy_set_header 设置镜像流量的头部

未分类

按照上述配置,搭建了上图所示的验证环境,各个模块均部署在本机,由curl发起请求:

curl 127.0.0.1

original和mirror均为上游server PHP脚本,其中original返回响应response to client。 抓包结果如下图:

未分类

分析抓包结果,整个请求流程为:

  • curl向nginx 80端口发起GET / HTTP请求

  • nginx将请求转发至upstream 9502端口的original php脚本,nginx本地端口为51637

  • nginx将请求镜像发至upstream 8081端口的mirror PHP脚本,nginx本地端口为51638

  • original发送响应response to client至nginx

  • nginx将响应转发至curl,curl将响应展示到终端

  • mirror将响应发送至nginx,nginx丢弃。

由此可见,在整个流程中,nginx将请求转发送至original和mirror,然后等待响应,几乎不会对正常请求造成影响,整个处理过程是完全异步的。

三、mirror模块实现

static ngx_int_t
ngx_http_mirror_handler_internal(ngx_http_request_t *r)
{
    ngx_str_t                   *name;
    ngx_uint_t                   i;
    ngx_http_request_t          *sr;
    ngx_http_mirror_loc_conf_t  *mlcf;

    mlcf = ngx_http_get_module_loc_conf(r, ngx_http_mirror_module);

    name = mlcf->mirror->elts;

    for (i = 0; i < mlcf->mirror->nelts; i++) {
        if (ngx_http_subrequest(r, &name[i], &r->args, &sr, NULL,
                                NGX_HTTP_SUBREQUEST_BACKGROUND)
            != NGX_OK)
        {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        sr->header_only = 1;
        sr->method = r->method;
        sr->method_name = r->method_name;
    }

    return NGX_DECLINED;
}

nginx有关mirror的代码位于文件src/http/modules/ngx_http_mirror_module.c文件,上述为文件中的ngx_http_mirror_handler_internal函数。在开启了mirror之后此函数会被执行,可见其内部主要通过ngx_http_subrequest发起http子请求来实现的。

通过代码可见,nginx支持配置多个mirror uri,示例为:

location / {
    mirror /mirror;
    mirror /mirror2;
    mirror_request_body off;
    proxy_pass http://127.0.0.1:9502;
}

location /mirror {
    internal;
    proxy_pass http://127.0.0.1:8081$request_uri;
}

location /mirror2 {
    internal;
    proxy_pass http://127.0.0.1:8081$request_uri;
}

如何使用Bash解析nginx.conf中server_name的第一个域名

问题

在指定的nginx.conf vhost配置文件中,如何获取server_name变量的第一个域名?
vhosts配置文件是与nginx.conf分离的,通过include引入,现在我能使用grep显示server_name的行内容,不过我仅想要第一个域名。
所以,如果我执行grep “server_name” /each/vhost/conf,将输出:

root@getyou:/home# grep "server_name" /home/site-configs/getyou
        server_name getyou.onl;
        server_name www.getyou.onl getme.onl www.getme.onl;
root@getyou:/home# grep "server_name" /home/site-configs/kevinpirnie
        server_name kevinpirnie.com www.kevinpirnie.com;
root@getyou:/home# grep "server_name" /home/site-configs/airsweepinc
        server_name airsweepinc.com www.airsweepinc.com;
root@getyou:/home# grep "server_name" /home/site-configs/themedepot
        server_name theme-depot.net www.theme-depot.net;

而我想输入下面的:

root@getyou:/home# grep "server_name" /home/site-configs/getyou
        getyou.onl
root@getyou:/home# grep "server_name" /home/site-configs/kevinpirnie
        kevinpirnie.com
root@getyou:/home# grep "server_name" /home/site-configs/airsweepinc
        airsweepinc.com
root@getyou:/home# grep "server_name" /home/site-configs/themedepot
        theme-depot.net

最佳答案

使用GNU grep和Perl正则:

$ grep -m1 -Poe 'server_name K[^; ]+' getyou
getyou.onl

(-m1 仅获取第一个匹配,-P Perl正则,-o 只打印匹配的部分。K 这之前匹配的都废弃,所以这之后的将由于-o打印)
或者,如果无法使用grep -P,可以使用同样效果的Perl:

$ perl -lne 'if (/server_name ([^ ;]+)/) {print $1; exit 0}' getyou

或者GNU sed:

$ sed -ne '/server_name/{s/.*server_name //; s/[; ].*//; p; q}' getyou

使用Python简单模拟Linux系统的tree工具

Linux系统中有个tree工具可以用比较好看的形式来显示指定文件夹的目录结构。例如下图(来自于网络):

未分类

本文代码使用Python对Linux系统的tree命令简单进行了模拟,不过还不是特别像,大家可以在此基础上进行改写或者扩展。

import os
import os.path


def tree(path, depth=0):
    if depth == 0:
        print(path)
    items = os.listdir(path)
    for item in items:
        # 输出文件夹中的文件和子文件夹名
        print('|    '*depth, end='')
        print('|----', item)
        item = os.path.join(path, item)
        if os.path.isdir(item):
            # 递归遍历子目录
            tree(item, depth+1)


tree(r'g:test')

运行结果:

未分类