海运的博客

Postfix和Dovecot配置Mysql虚拟用户

发布时间:March 26, 2014 // 分类:Mail // No Comments

安装:

yum install dovecot-mysql

新建数据库:

CREATE DATABASE mailserver;
GRANT SELECT ON mailserver.* TO 'mailuser'@'127.0.0.1' IDENTIFIED BY 'mailuserpass';
FLUSH PRIVILEGES;
USE mailserver;

#虚拟域表
CREATE TABLE `virtual_domains` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#虚拟用户表
CREATE TABLE `virtual_users` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `password` varchar(106) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#虚拟用户别名
CREATE TABLE `virtual_aliases` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `source` varchar(100) NOT NULL,
  `destination` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加测试数据:
INSERT INTO `mailserver`.`virtual_domains`
  (`name`)
VALUES
  ('haiyun.me');
INSERT INTO `mailserver`.`virtual_users`
  (`domain_id`, `password` , `email`)
VALUES
  ('1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'user@haiyun.me');
INSERT INTO `mailserver`.`virtual_aliases`
  (`domain_id`, `source`, `destination`)
VALUES
  ('1', 'alias@haiyun.me', 'user@haiyun.me');

Postfix添加以下配置:

virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
#使用dovecot lmtp交付虚拟域邮件,省却postfix配置用户邮件目录及权限问题
virtual_transport = lmtp:unix:private/dovecot-lmtp 
#使用dovecot验证,后面dovecot配置
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

smtpd_recipient_restrictions =
        permit_sasl_authenticated,
        permit_mynetworks,
        reject_unauth_destination

配置Postfix支持Mysql查询表:

#虚拟域
/etc/postfix/mysql-virtual-mailbox-domains.cf
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
#虚拟用户
/etc/postfix/mysql-virtual-mailbox-maps.cf 
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
#虚拟别名
/etc/postfix/mysql-virtual-alias-maps.cf 
user = mailuser
password = mailuserpass
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'

测试查询:

postmap -q haiyun.me mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
postmap -q user@haiyun.me mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
postmap -q alias@haiyun.me mysql:/etc/postfix/mysql-virtual-alias-maps.cf

Dovecot配置:

/etc/dovecot/conf.d/10-mail.conf 
mail_location = maildir:/var/mail/vhosts/%d/%n

/etc/dovecot/conf.d/10-auth.conf
auth_verbose = yes  # 认证详细日志  
auth_debug = yes    # 认证debug
disable_plaintext_auth = no #开启明文验证
auth_mechanisms = plain login #支持验证方法
#!include auth-system.conf.ext #取消默认系统验证
!include auth-sql.conf.ext #使用mysql验证

/etc/dovecot/conf.d/auth-sql.conf.ext
#用户验证
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
#用户邮箱目录 %d为domain,%n为user
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

/etc/dovecot/dovecot-sql.conf.ext
driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailuserpass
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

/etc/dovecot/conf.d/10-master.conf
#lmtp服务,postfix通过lmtp交付邮件
service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   mode = 0600
   user = postfix
   group = postfix
  }
}
#验证服务,postfix也通过此验证用户
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    #group =
  }
  user = dovecot
}
service auth-worker {
  user = vmail
}

新建用户用以访问邮件目录数据:

useradd -M -u 5000 vmail -d /var/mail -s /sbin/nologin 
chown -R vmail:vmail /var/mail/

参考:https://library.linode.com/email/postfix/postfix2.9.6-dovecot2.0.19-mysql

PHP下PCRE_UTF8 support

发布时间:March 22, 2014 // 分类:PHP // No Comments

在使用PHP pcre_match时遇到错误:

Compilation failed: this version of PCRE is not compiled with PCRE_UTF8 support at offset 0
pcretest -C
Compiled with UTF-8 not support

下载对应版本src rpm重新编译pcre:

yum install rpm-build
wget http://vault.centos.org/6.4/os/Source/SPackages/pcre-7.8-6.el6.src.rpm
rpmbuild --rebuild --with enable-utf8 pcre-7.8-6.el6.src.rpm

重新安装编译的软件包:

rpm -iv --replacepkgs /root/rpmbuild/RPMS/i386/pcre-7.8-6.el6.i386.rpm 

Nginx下使用Awstats

发布时间:February 27, 2014 // 分类:日记分析 // No Comments

1.生成静态html:

/usr/local/awstats/tools/awstats_buildstaticpages.pl -update -config=www.haiyun.me \
-lang=cn -dir=/home/wwwroot/awstats/

Nginx配置:

server {
  listen 80;
  server_name awstats.haiyun.me;
  access_log /var/log/nginx/awstats.log main;
  root /home/wwwroot/awstats;
  index index.html;

  # Restrict access
  #auth_basic "Restricted";
  #auth_basic_user_file /etc/awstats/htpasswd;

  location /css/ {
    alias /usr/local/awstats/wwwroot/css/;
  }

  location /icon/ {
    alias /usr/local/awstats/wwwroot/icon/;
  }

  location /js/ {
    alias /usr/local/awstats/wwwroot/js/;
  }
}

2.使用fcgi:

cd /usr/local/awstats/tools/nginx/
cp awstats-fcgi.php ../../wwwroot/cgi-bin/fcgi.php 
server {
  listen       80 default_server;
  server_name  _;

  access_log  /home/wwwlogs/access.log  main;

  root   /home/wwwroot/default;
  index  index.htm index.html index.php;

  location ~ ^/cgi-bin/.*\.(cgi|pl|py|rb) {
    gzip off;
    root   /usr/local/awstats/wwwroot;
    fastcgi_pass unix:/tmp/php-cgi.sock;
    include fastcgi.conf; 
    fastcgi_param SCRIPT_FILENAME    $document_root/cgi-bin/fcgi.php;
    fastcgi_param X_SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
    fastcgi_param X_SCRIPT_NAME      $fastcgi_script_name;
  }

  location /icon/ {
    alias /usr/local/awstats/wwwroot/icon/;
  }

  location /css/ {
    alias /usr/local/awstats/wwwroot/css/;
  }

  location /js/ {
    alias /usr/local/awstats/wwwroot/js/;
  }

}

字符转URL

发布时间:February 8, 2014 // 分类:PHP // No Comments

英文:

function tourl($str) {
  $str = preg_replace('/[^a-zA-Z0-9]+/', '-', $str);
  $str = trim($str, '-');
  return strtolower($str);
}

包含特殊字符:

function strtourl($str) {
  $str = htmlentities($str, ENT_QUOTES, "UTF-8");
  $str = preg_replace('/&([a-z]{1,2})(?:acute|lig|grave|ring|tilde|uml|cedil|caron);/i','\1',$str);
  $str = html_entity_decode($str, ENT_QUOTES, "UTF-8");
  $str = preg_replace('/[^a-z0-9]+/i', '-', $str);
  return strtolower($str);
}

Nginx rewrite 指令last break区别

发布时间:February 8, 2014 // 分类:Nginx // No Comments

nginx 的官方注释是这样的:

last
   stops processing the current set of ngx_http_rewrite_module directives followed by a search for a new location matching the changed URI;

break
   stops processing the current set of ngx_http_rewrite_module directives;

我们知道nginx运行分十一个执行阶段,上面说提到的ngx_http_rewrite_mode,可以理解为其中一个阶段-rewrite阶段。​

typedef enum {
    NGX_HTTP_POST_READ_PHASE = 0,
    NGX_HTTP_SERVER_REWRITE_PHASE,
    NGX_HTTP_FIND_CONFIG_PHASE,
    NGX_HTTP_REWRITE_PHASE,           //rewrite阶段在这里
    NGX_HTTP_POST_REWRITE_PHASE,
    NGX_HTTP_PREACCESS_PHASE,
    NGX_HTTP_ACCESS_PHASE,
    NGX_HTTP_POST_ACCESS_PHASE,
    NGX_HTTP_TRY_FILES_PHASE,
    NGX_HTTP_CONTENT_PHASE,
    NGX_HTTP_LOG_PHASE
} ngx_http_phases;

所以我们再来理解last与break的区别:
last: 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行…
break:相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段…
我们来看一个例子:

server {
    listen 80 default_server;
    server_name dcshi.com;
    root www;

    location /break/ {
        rewrite ^/break/(.*) /test/$1 break;
        echo "break page";
    } 

    location /last/ {
         rewrite ^/last/(.*) /test/$1 last;
         echo "last page";
    }    

    location /test/ {
       echo "test page";
    }
}

请求:http://dcshi.com/break/*
输出: break page
分析:正如上面讨论所说,break是跳过当前请求的rewrite阶段,并继续执行本请求的其他阶段,很明显,对于/foo 对应的content阶段的输出为 echo “break page”; (content阶段,可以简单理解为产生数据输出的阶段,如返回静态页面内容也是在content阶段;echo指令也是运行在content阶段,一般情况下content阶段只能对应一个输出指令,如同一个location配置两个echo,最终只会有一个echo指令被执行);当然如果你把/break/里的echo 指令注释,然后再次访问/break/xx会报404,这也跟我们预期一样:虽然/break/xx被重定向到/test/xx,但是break指令不会重新开启一个新的请求继续匹配,所以nginx是不会匹配到下面的/test/这个location;在echo指令被注释的情况下,/break/ 这location里只能执行nginx默认的content指令,即尝试找/test/xx这个html页面并输出起内容,事实上,这个页面不存在,所以会报404的错误。

请求: http://dcshi.com/last/*
输出: test page
分析: last与break最大的不同是,last会重新发起一个新请求,并重新匹配location,所以对于/last,重新匹配请求以后会匹配到/test/,所以最终对应的content阶段的输出是test page;

假设你对nginx的运行阶段有一个大概的理解,对理解last与break就没有问题了。

原文:http://www.dcshi.com/?p=172

分类
最新文章
最近回复
  • opnfense: 谢谢博主!!!解决问题了!!!我之前一直以为内置的odhcp6就是唯一管理ipv6的方式
  • liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
  • 海运: 不好意思,没有。
  • zongboa: 您好,請問一下有immortalwrt設定guest Wi-Fi的GUI教學嗎?感謝您。
  • 海运: 恩山有很多。
  • swsend: 大佬可以分享一下固件吗,谢谢。
  • Jimmy: 方法一 nghtp3步骤需要改成如下才能编译成功: git clone https://git...
  • 海运: 地址格式和udpxy一样,udpxy和msd_lite能用这个就能用。
  • 1: 怎么用 编译后的程序在家里路由器内任意一台设备上运行就可以吗?比如笔记本电脑 m参数是笔记本的...
  • 孤狼: ups_status_set: seems that UPS [BK650M2-CH] is ...
归档