⑴ linux中进程 kacpid, kblockd是什么
守护进程及调度进程,以下是摘录的一些常用进程的说明:
/sbin/init 内核启动的第一个用户级进程,引导用户空间服务
[kthreadd] 内核线程管理
[migration/0] 用于进程在不同的CPU间迁移
[ksoftirqd/0] 内核调度/管理第0个CPU软中断的守护进程
[migration/1] 管理多核心
[ksoftirqd/1] 内核调度/管理第1个CPU软中断的守护进程
[events/0] 处理内核事件守护进程
[events/1] 处理内核事件守护进程
[cpuset] 在每个处理器上单独运行进程,通过文件系统实现
[khelper] 内核帮助进程
[netns] 网络仿真器,模拟网络环境
[async/mgr] 异步加密管理进程
[pm] 包管理
[sync_supers] 特权同步,将缓冲区文件强制写入硬盘
[bdi-default] JTAG调试器默认进程
[kintegrityd/0] 内核完整性检查
[kintegrityd/1] 内核完整性检查
[kblockd/0] 管理磁盘块读写
[kblockd/1] 管理磁盘块读写
[kacpid] 高级配置和电源管理接口
[kacpi_notify] acpi进程的通知进程
[kacpi_hotplug] acpi热插拔管理
[ata/0] ATA硬盘接口管理
[ata/1] ATA硬盘接口管理
[ata_aux] ATA硬盘接口管理
[khubd] 内核的usb hub
[kseriod] 内核线程
[kswapd0] 内存回收,确保系统空闲物理内存的数量在一个合适的范围
[ksmd] 作为内核中的守护进程存在,它定期执行页面扫描,识别副本页面并合并副本,释放这些页面以供它用
[aio/0] 代替用户进程管理io
[aio/1] 代替用户进程管理io
[ecryptfs-kthrea] 加密系统
[crypto/0] 提供加密解密相关函数
[crypto/1] 提供加密解密相关函数
[scsi_eh_0] scsi设备
[scsi_eh_1] scsi设备
[scsi_eh_2] scsi设备
[scsi_eh_3] scsi设备
[kpsmoused] 内核鼠标支持
[kjournald] Ext3文件系统的日志管理
[kjournald] Ext3文件系统的日志管理
[flush-1:0] 释放存储在缓存区中的数据
[flush-1:1] 释放存储在缓存区中的数据
[flush-1:2] 释放存储在缓存区中的数据
[flush-1:3] 释放存储在缓存区中的数据
[flush-1:4] 释放存储在缓存区中的数据
[flush-1:5] 释放存储在缓存区中的数据
[flush-1:6] 释放存储在缓存区中的数据
[flush-1:7] 释放存储在缓存区中的数据
[flush-1:8] 释放存储在缓存区中的数据
[flush-1:9] 释放存储在缓存区中的数据
[flush-1:10] 释放存储在缓存区中的数据
[flush-1:11] 释放存储在缓存区中的数据
[flush-1:12] 释放存储在缓存区中的数据
[flush-1:13] 释放存储在缓存区中的数据
[flush-1:14] 释放存储在缓存区中的数据
[flush-1:15] 释放存储在缓存区中的数据
[flush-8:0] 释放存储在缓存区中的数据
[kjournald] Ext3文件系统的日志管理
[loop0] 负责对loop设备进行操作
[loop1] 负责对loop设备进行操作
[loop2] 负责对loop设备进行操作
[kd] 内核拷贝线程
[ext4-dio-unwrit] Ext4文件系统相关线程
upstart-udev-bridge --daemon 一个守护进程,负责接收udev信息
udevd --daemon 一个守护进程,在向udev提交之前重新订制热插拔事件,从而避免各种各样的竞争条件
/usr/sbin/restorecond 用于给SELinux监测和重新加载正确的文件上下文
/sbin/auditd 审计守护进程
/sbin/audispd 审计调度进程
[kauditd] 内核审核守护进程
/sbin/getty -8 38400 tty4 等待用户从tty4登录
/sbin/getty -8 38400 tty5 等待用户从tty5登录
/sbin/getty -8 38400 tty2 等待用户从tty2登录
/sbin/getty -8 38400 tty3 等待用户从tty3登录
/sbin/getty -8 38400 tty6 等待用户从tty6登录
acpid -c /etc/acpi/events -s /var/run/acpid.socket 一个用户空间的服务进程,它充当Linux内核与应用程序之间通信的接口
cron 守护进程,周期地运行用户调度的任务
/sbin/getty -8 38400 tty1 等待用户从tty1登录
X :0 -br vt7 -nolisten tcp Xsever
[flush-252:0] 释放存储在缓存区中的数据
lwm 窗口管理器
fcitx 输入法
su 切换root用户
bash 终端
ps x 查看当前用户的进程
⑵ Linux中的set命令的详细解释
linxu下的set命令是用来设置各种shell选项或者列出shell变量。下面由我为大家整理了linux的set命令的详细解释的相关知识,希望对大家有帮助!
一、Linux中的set命令的详细解释
功能说明:设置shell。
语法:set [+-abCdefhHklmnpPtuvx]
补充说明:用set 命令可以设置各种shell选项或者列 出shell变量.单个选项设置常用的特性.在某些选项之后-o参数将特殊特性打开.在某些选项之后使用+o参数将关闭某些特性,不带任何参数的set命 令将显示shell的全部变量.除非遇到非法的选项,否则set总是返回ture.
参数:
allexport -a 从设置开始标记所有新的和修改过的用于输出的变量
braceexpand -B 允许符号扩展,默认选项
emacs 在进行命令编辑的时候,使用内建的emacs编辑器, 默认选项
errexit -e 如果一个命令返回一个非0退出状态值(失败),就退出.
histexpand -H 在做临时替换的时候允许使用!和!! 默认选项
history 允许命令行历史,默认选项
ignoreeof 禁止coontrol-D的方式退出shell,必须输入exit。
interactive-comments 在交互式模式下, #用来表示注解
keyword -k 为命令把关键字参数放在环境中
monitor -m 允许作业控制
noclobber -C 保护文件在使用重新动向的时候不被覆盖
noexec -n 在脚本状态下读取命令但是不执行,主要为了检查语法结构。
noglob -d 禁止路径名扩展,即关闭通配符
notify -b 在后台作业以后通知客户
nounset -u 在扩展一个没有的设置的变量的时候, 显示错误的信息
onecmd -t 在读取并执行一个新的命令后退出
physical -P 如果被设置,则在使用pwd和cd命令时不使用符号连接的路径 而是物理路径
posix 改变shell行为以便符合POSIX要求
privileged 一旦被设置,shell不再读取.profile文件和env文件 shell函数也不继承任何环境
verbose -v 为调试打开verbose模式
vi 在命令行编辑的时候使用内置的vi编辑器
xtrace -x 打开调试回响模式
二、Linux中的set命令详解实例
显示环境变量
# set
BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="3" [1]="00" [2]="15" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu")
BASH_VERSION='3.00.15(1)-release'
COLORS=/etc/DIR_COLORS.xterm
COLUMNS=99
DIRSTACK=()
EUID=0
GROUPS=()
G_BROKEN_FILENAMES=1
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/root
HOSTNAME=hnlinux
HOSTTYPE=i386
IFS=$' '
INPUTRC=/etc/inputrc
KDEDIR=/usr
LANG=zh_CN.GB2312
LESSOPEN='|/usr/bin/lesspipe.sh %s'
LINES=34
L
MAIL=/var/spool/mail/root
MAILCHECK=60
OLDPWD=/home/uptech
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin:/opt/crosstools/gcc-3.4.6-glibc-2.3.6/bin
PIPESTATUS=([0]="2")
PPID=26005
PROMPT_COMMAND='echo -ne "
三、Linux的set命令的相关扩展
set、env、export——Linux中的环境变量命令
Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境 变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。
什么是环境变量
环境变量是一个具有 特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。许多用户(特别是那些刚接触Linux的新手)发现这些变量有些怪异或者难以控制。其 实,这是个误会:通过使用环境变量,你可以很容易的修改一个牵涉到一个或多个应用程序的配置信息。
常见的环境变量
对于 PATH和HOME等环境变量大家都不陌生。
PATH能够指定命令的搜索路径,那么动态链接库的路径用什么变量指定呢?或者就是在 PATH里面?
比如有一个程序需要/usr/local/lib下面的一个库文件,应该怎么指定其路径呢?
经常看到有些变量如 LD_LIBRARY_PATH,LIBPATH,CLASSPATH等,他们之间有什么不同和关系?
除此之外,还有下面一些常见环境变 量。
◆ HISTSIZE是指保存历史命令记录的条数。
◆ LOGNAME是指当前用户的登录名。
◆ HOSTNAME是指主机的名称,许多应用程序如果要用到主机名的话,通常是从这个环境变量中来取得的。
◆ SHELL是指当前用户用的是哪种Shell。
◆ LANG/LANGUGE是和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。
◆ MAIL是指当前用户的邮件存放目录。
◆ PS1是基本提示符,对于root用户是#,对于普通用户是$。PS2是附属提示符,默认是“>”。可以通过修改此环境变量来修改当前的命令符,比 如下列命令会将提示符修改成字符串“Hello,My NewPrompt ”。
⑶ 如何在Linux命令行中通过SMTP服务器发送电子邮件
假定你想配置一个 Linux 应用,用于从你的服务器或桌面客户端发送邮件信息。邮件信息可能是邮件简报、状态更新(如 Cachet)、监控警报(如 Monit)、磁盘时间(如 RAID mdadm)等等。当你要建立自己的 邮件发送服务器 传递信息时 ,你可以替代使用一个免费的公共 SMTP 服务器,从而避免遭受维护之苦。
谷歌的 Gmail 服务就是最可靠的 免费 SMTP 服务器 之一。想要从应用中发送邮件通知,你仅需在应用中添加 Gmail 的 SMTP 服务器地址和你的身份凭证即可。
使用 Gmail 的 SMTP
服务器会遇到一些限制,这些限制主要用于阻止那些经常滥用服务器来发送垃圾邮件和使用邮件营销的家伙。举个例子,你一次只能给至多 100
个地址发送信息,并且一天不能超过 500
个收件人。同样,如果你不想被标为垃圾邮件发送者,你就不能发送过多的不可投递的邮件。当你达到任何一个限制,你的 Gmail
账户将被暂时的锁定一天。简而言之,Gmail 的 SMTP 服务器对于你个人的使用是非常棒的,但不适合商业的批量邮件。
说了这么多,是时候向你们展示 如何在 Linux 环境下使用 Gmail 的 SMTP 服务器 了。
Google Gmail SMTP 服务器设置
如果你想要通过你的应用使用 Gmail 的 SMTP 服务器发送邮件,请牢记接下来的详细说明。
邮件发送服务器 (SMTP 服务器): smtp.gmail.com
使用认证: 是
使用安全连接: 是
用户名: 你的 Gmail 账户 ID (比如 "alice" ,如果你的邮箱为 [email protected])
密码: 你的 Gmail 密码
端口: 587
确切的配置根据应用会有所不同。在本教程的剩余部分,我将向你展示一些在 Linux 上使用 Gmail SMTP 服务器的应用示例。
从命令行发送邮件
作为第一个例子,让我们尝试最基本的邮件功能:使用 Gmail SMTP 服务器从命令行发送一封邮件。为此,我将使用一个称为 mutt 的命令行邮件客户端。
先安装 mutt:
对于 Debian-based 系统:
$ sudo apt-get install mutt
对于 Red Hat based 系统:
$ sudo yum install mutt
创建一个 mutt 配置文件(~/.muttrc),并和下面一样,在文件中指定 Gmail SMTP 服务器信息。将 替换成自己的 Gmail ID。注意该配置只是为了发送邮件而已(而非接收邮件)。
$ vi ~/.muttrc
set from = "@gmail.com"set realname = "Dan Nanni"set smtp_url = "smtp://@smtp.gmail.com:587/"set smtp_pass = ""
一切就绪,使用 mutt 发送一封邮件:
$ echo "This is an email body." | mutt -s "This is an email subject" [email protected]
想在一封邮件中添加附件,使用 "-a" 选项
$ echo "This is an email body." | mutt -s "This is an email subject" [email protected] -a ~/test_attachment.jpg
使用 Gmail SMTP 服务器意味着邮件将显示是从你 Gmail 账户发出的。换句话说,收件人将视你的 Gmail 地址为发件人地址。如果你想要使用自己的域名作为邮件发送方,你需要使用 Gmail SMTP 转发服务。
当服务器重启时发送邮件通知
如果你在 虚拟专用服务器(VPS)
上跑了些重要的网站,建议监控 VPS 的重启行为。作为一个更为实用的例子,让我们研究如何在你的 VPS
上为每一次重启事件建立邮件通知。这里假设你的 VPS 上使用的是 systemd,并向你展示如何为自动邮件通知创建一个自定义的 systemd
启动服务。
首先创建下面的脚本 reboot_notify.sh,用于负责邮件通知。
$ sudo vi /usr/local/bin/reboot_notify.sh
#!/bin/sh
echo "`hostname` was rebooted on `date`" | mutt -F /etc/muttrc -s "Notification on `hostname`" [email protected]
$ sudo chmod +x /usr/local/bin/reboot_notify.sh
在这个脚本中,我使用 "-F" 选项,用于指定系统级的 mutt 配置文件位置。因此不要忘了创建 /etc/muttrc 文件,并如前面描述的那样填入 Gmail SMTP 信息。
现在让我们创建如下一个自定义的 systemd 服务。
$ sudo mkdir -p /usr/local/lib/systemd/system$ sudo vi /usr/local/lib/systemd/system/reboot-task.service
[Unit]
Description=Send a notification email when the server gets rebooted
DefaultDependencies=no
Before=reboot.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/reboot_notify.sh
[Install]
WantedBy=reboot.target
在创建服务后,添加并启动该服务。
$ sudo systemctl enable reboot-task$ sudo systemctl start reboot-task
从现在起,在每次 VPS 重启时,你将会收到一封通知邮件。
通过服务器使用监控发送邮件通知
作为最后一个例子,让我展示一个现实生活中的应用程序,Monit,这是一款极其有用的服务器监控应用程序。它带有全面的 VPS 监控能力(比如 CPU、内存、进程、文件系统)和邮件通知功能。
如果你想要接收 VPS 上由 Monit 产生的任何事件的邮件通知,你可以在 Monit 配置文件中添加以下 SMTP 信息。
set mailserver smtp.gmail.com port 587
username "" password ""
using tlsv12
set mail-format {
from: @gmail.com
subject: $SERVICE $EVENT at $DATE on $HOST
message: Monit $ACTION $SERVICE $EVENT at $DATE on $HOST : $DESCRIPTION.
Yours sincerely,
Monit
}
# the person who will receive notification emails
set alert [email protected]
这是一个因为 CPU 负载超载而由 Monit 发送的邮件通知的例子。
⑷ linux下多个定时器的实现(C语言),麻烦高手指点哈嘛(急)
给你两个函数参考
omsTimer函数是处理定时事件,void(*handle)(union sigval v)参数就是处理事件的函数指针。
int omsSetTimer(timer_t *tId,int value,int interval)就是设置定时器。
按你说的,如果要同时起多个定时器,需要定义一个数组timer_t tm[n];int it[n];tm就是定时器结构,it用来记录对应的定时器是否已经使用,使用中的就是1,没用的就是0;
主进程消息来了就从it找一个没用的来omsSetTimer,如果收到终止消息,那omsSetTimer 定时时间为0
int omsTimer(timer_t *tId,int iValue,int iSeconds ,void(*handle)(union sigval v),void * param)
{
struct sigevent se;
struct itimerspec ts;
memset (&se, 0, sizeof (se));
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = handle;
se.sigev_value.sival_ptr = param;
if (timer_create (CLOCK_REALTIME, &se, tId) < 0)
{
return -1;
}
ts.it_value.tv_sec = iValue;
// ts.it_value.tv_sec =3;
//ts.it_value.tv_nsec = (long)(iValue % 1000) * (1000000L);
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = iSeconds;
//ts.it_interval.tv_nsec = (long)(iSeconds % 1000) * (1000000L);
ts.it_interval.tv_nsec = 0;
if (timer_settime(*tId, TIMER_ABSTIME, &ts, NULL) < 0)
{
return -1;
}
return 0;
}
int omsSetTimer(timer_t *tId,int value,int interval)
{
struct itimerspec ts;
ts.it_value.tv_sec =value;
//ts.it_value.tv_nsec = (long)(value % 1000) * (1000000L);
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = interval;
//ts.it_interval.tv_nsec = (long)(interval % 1000) * (1000000L);
ts.it_interval.tv_nsec = 0;
if (timer_settime(*tId, TIMER_ABSTIME, &ts, NULL) < 0)
{
return -1;
}
return 0;
}
⑸ 在linux环境中,如何实现多线程中使用多个定时器,POSIX定时器可以吗,如何用
个人解决了,以下是一个实现:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#if 1
pthread_attr_t attr;
timer_t hard_timer, software_timer;
struct sigevent hard_evp, software_evp;
static void watchdog_hard_timeout(union sigval v)
{
time_t t;
char p[32];
timer_t *q;
struct itimerspec ts;
int ret;
time(&t);
strftime(p, sizeof(p), "%T", localtime(&t));
printf("watchdog hard timeout!\n");
printf("%s thread %d, val = %u, signal captured.\n", p, (unsigned int)pthread_self(), v.sival_int);
q = (timer_t *)(v.sival_ptr);
printf("hard timer_t:%d add:%p, q:%p!\n", (int)hard_timer, &hard_timer, q);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 6;
ts.it_value.tv_nsec = 0;
ret = timer_settime(*q, CLOCK_REALTIME, &ts, NULL);
if (ret != 0) {
printf("settime err(%d)!\n", ret);
}
}
static void watchdog_software_timeout(union sigval v)
{
time_t t;
char p[32];
timer_t *q;
struct itimerspec ts;
int ret;
time(&t);
strftime(p, sizeof(p), "%T", localtime(&t));
printf("watchdog software timeout!\n");
printf("%s thread %d, val = %u, signal captured.\n", p, (unsigned int)pthread_self(), v.sival_int);
q = (timer_t *)(v.sival_ptr);
printf("hard timer_t:%d add:%p, q:%p!\n", (int)hard_timer, &hard_timer, q);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 10;
ts.it_value.tv_nsec = 0;
ret = timer_settime(*q, CLOCK_REALTIME, &ts, NULL);
if (ret != 0) {
printf("settime err(%d)!\n", ret);
}
}
static void dcmi_sol_pthread_attr_destroy(pthread_attr_t *attr)
{
pthread_attr_destroy(attr);
}
static int dcmi_sol_pthread_attr_init(pthread_attr_t *attr)
{
int ret;
if ((ret = pthread_attr_init(attr) != 0)) {
goto err;
}
if ((ret = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)) != 0) {
dcmi_sol_pthread_attr_destroy(attr);
goto err;
}
/* 设置线程的栈大小,失败则用系统默认值 */
pthread_attr_setstacksize(attr, 128 * 1024);
return 0;
err:
printf("set ptread attr failed(ret:%d)!\n", ret);
return -1;
}
int main(void)
{
struct itimerspec ts;
int ret;
ret = dcmi_sol_pthread_attr_init(&attr);
if (ret != 0) {
printf("init pthread attributes fail(%d)!\n", ret);
exit(-1);
}
memset(&hard_evp, 0, sizeof(struct sigevent));
hard_evp.sigev_value.sival_ptr = &hard_timer;
hard_evp.sigev_notify = SIGEV_THREAD;
hard_evp.sigev_notify_function = watchdog_hard_timeout;
hard_evp.sigev_notify_attributes = NULL;//&attr;
memset(&software_evp, 0, sizeof(struct sigevent));
software_evp.sigev_value.sival_ptr = &software_timer;
software_evp.sigev_notify = SIGEV_THREAD;
software_evp.sigev_notify_function = watchdog_software_timeout;
software_evp.sigev_notify_attributes = NULL;//&attr;
ret = timer_create(CLOCK_REALTIME, &hard_evp, &hard_timer);
if(ret != 0) {
perror("hard timer_create fail!");
exit(-1);
}
ret = timer_create(CLOCK_REALTIME, &software_evp, &software_timer);
if (ret != 0) {
timer_delete(hard_timer);
perror("software timer_create fail!");
exit(-1);
}
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 6;
ts.it_value.tv_nsec = 0;
ret = timer_settime(hard_timer, CLOCK_REALTIME, &ts, NULL);
if(ret != 0) {
perror("hard timer_settime fail!");
timer_delete(hard_timer);
timer_delete(software_timer);
exit(-1);
}
ts.it_value.tv_sec = 10;
ret = timer_settime(software_timer, CLOCK_REALTIME, &ts, NULL);
if(ret != 0) {
perror("hard timer_settime fail!");
timer_delete(hard_timer);
timer_delete(software_timer);
exit(-1);
}
while(1) {
printf("main ready sleep!\n");
sleep(15);
printf("main sleep finish!\n");
}
return 0;
}
#endif
⑹ linux下如何安装邮件系统postfixlinux下如何对邮件系统postfix设置
postfix的安装过程
3.1原始码包的安装
1. 获取postfix的原始码包
从postfix官方站点www.postfix.org取得postfix的原始码包postfix-19991231-pl08.tar.gz。将其拷贝到/tmp
2.解开原始码包,将生成/tmp/ postfix-19991231-pl08目录。
tar xvzf postfix-19991231-pl08.tar.gz
3.编译原始码包
cd /tmp/ postfix-19991231-pl08
make
4.建立一个新用户“postfix”,该用户必须具有唯一的用户id和组id号,同时应该让该用户不能登录到系统,也即不为该用户指定可执行的登录外壳程式和可用的用户宿主目录。我们能先用adser postfix 添加用户再编辑/etc/passwd文件中的相关条目如下所示:
postfix:*:12345:12345:postfix:/no/where:/no/shell
5.确定/etc/aliases文件中包含如下的条目:
postfix: root
6. 以root用户登录,在/tmp/ postfix-19991231-pl08目录下执行命令:
./install.sh
7. 启动postfix
# postfix start
8.关于maildrop目录权限的说明:
postfix能使用一个所有用户都可写的(也即目录权限为1773)的maildrop
目录来让本地用户提交邮件。这种方法避免了使用set-uid 或 set-gid 软件,并且在邮件系统不可用时,用户仍然能提交邮件。其他用户没有访问该目录中的队列文件的权限。接收来自网络的邮件时postfix不使用maildrop目录。不过,由于该目录的权限是733,其他用户能建立一个硬连接到该目录中的文件从而导致该邮件被投递多次或无法删除,也就是说这将导致安全性问题。如果你想要使用这种方式来让用户提交邮件,就要在install.sh 脚本问你是否需要set-gid 时回答no。
如果你的系统有多个用户的话,最佳取消以上的方式而采用利用set-gid 用
户权限提交邮件的方式。这时,我们首先需要建立一个组id唯一的组"maildrop" 并且确定该组中没有用户成员。然后在install.sh 问你是否需要set-gid 时指定"maildrop"。
提示:在安装postfix之前,请删除已安装的sendmail。
3.2 rpm包的安装
1. 获取postfix的rpm软件包。
我们能从http://www.alltrading.es/postfix/rpms/i386/ 获得postfix的rpm软件包。当前的最新版本是postfix-20000531-2.i386.rpm。
2. 备份你的/etc/aliases和/etc/aliases.db,因为postfix要使用该别名数据库。
3. 用以下命令查看系统是否安装了sendmail:
[root@mail /root]# rpm -qa |grep sendmail
sendmail-doc-8.9.3-15
sendmail-8.9.3-15
sendmail-cf-8.9.3-15
4. 用以下命令强行卸载sendmail:
[root@mail /root]# rpm -e sendmail sendmail-cf sendmail-doc --nodeps
5. 用以下命令杀死运行中的sendmail进程:
[root@mail /root]# killall sendmail
6. 安装postfix:
7. 启动postfix
[root@mail /root]# /etc/rc.d/init.d/postfix start
3.3 设置系统每次启动时自动启动postfix
1.如果你安装的是postfix的原始码包,能在/etc/rc.d/rc.local文件中加入如下的语句让系统每次启动时自动启动postfix:
if [ -f /usr/libexec/postfix ]; then
/usr/libexec/postfix start
fi
2.如果你安装的是postfix的rpm包,能通过setup命令来设置在系统启动时启动postfix。
四、 postfix的设置详解
4.1 postfix的设置文件结构
postfix的设置文件位于/etc/postfix下,安装完postfix以后,我们能通过ls命令查看postfix的设置文件:
[root@mail postfix]# ls
install.cf main.cf master.cf postfix-script
这四个文件就是postfix最基本的设置文件,他们的差别在于:
mail.cf:是postfix主要的设置文件。
install.cf:包含安装过程中安装程式产生的postfix初始化设置。
master.cf:是postfix的master进程的设置文件,该文件中的每一行都是用来设置postfix的组件进程的运行方式。
postfix-script:包装了一些postfix命令,以便我们在linux环境中安全地执行这些postfix命令。
4.2 postfix的基本设置
postfix大约有100个设置参数,这些参数都能通过main.cf 指定。设置的格式是这样的,用等号连接参数和参数的值。如:
myhostname = mail.mydomain.com
等号的左边是参数的名称,等号的右边是参数的值; 当然,我们也能在参数的前面加上$来引用该参数,如:
myorigin = $myhostname
虽然postfix有100个左右的参数,不过postfix为大多数的参数都设置了缺省值,所以在让postfix正常为你服务之前,你只需要设置为数不多的几个参数。下面我们一起来看一看这些基本的postfix参数。需要注意的是,一旦你更改了main.cf文件的内容,则必须运行postfix reload命令使其生效。
1. myorigin
myorigin参数指明发件人所在的域名。如果你的用户的邮件地址为[email protected],则该参数指定@后面的域名。缺省地,postfix使用本地主机名作为myorigin,不过建议你最佳使用你的域名,因为这样更具有可读性。比如:安装postfix的主机为mail.domain.com则我们能这样指定myorigin:
myorigin = domain.com
当然我们也能引用其他参数,如:
myorigin = $mydomain
2. mydestination
mydestination参数指定postfix接收邮件时收件人的域名,换句话说,也就
是你的postfix系统要接收什么样的邮件。比如:你的用户的邮件地址为[email protected], 也就是你的域为domain.com, 则你就需要接收所有收件人为[email protected]的邮件。和myorigin相同,缺省地,postfix使用本地主机名作为mydestination。
3. notify_classes
在postfix系统中,必须指定一个postfix系统管理员的别名指向一个用户,
只有这样,在用户遇见问题时才有报告的对象,postfix也才能将系统的问题报告给管理员。notify_classes参数就是用来指定向postfix管理员报告错误时的信息级别。共有以下几种级别:
bounce:将不能投递的邮件的拷贝发送给postfix管理员。出于个人隐私的缘故,该邮件的拷贝不包含信头。
2bounce:将两次不可投递的邮件拷贝发送给postfix管理员。
delay:将邮件的投递延迟信息发送给管理员,仅仅包含信头。
policy:将由于uce规则限制而被拒绝的用户请求发送给postfix管理员,包含整个smtp会话的内容。
protocol:将协议的错误信息或用户企图执行不支持的命令的记录发送给postfix管理员。同样包含整个smtp会话的内容。
resource:将由于资源错误而不可投递的错误信息发送给postfix管理员,比如:队列文件写错误等等。
software:将由于软件错误而导致不可投递的错误信息发送给postfix管理员。
缺省值为:
notify_classes = resource, software
4.myhostname
myhostname 参数指定运行postfix邮件系统的主机的主机名。缺省地,该值被设定为本地机器名。你也能指定该值,需要注意的是,要指定完整的主机名。如:
myhostname = mail.domain.com
5.mydomain
mydomain参数指定你的域名,缺省地,postfix将myhostname的第一部分删除而作为mydomain的值。你也能自己指定该值,
6.mynetworks
mynetworks 参数指定你所在的网络的网络地址,postfix系统根据其值来差别用户是远程的还是本地的,如果是本地网络用户则允许其访问。你能用标准的a、b、c类网络地址,也能用cidr(无类域间路由)地址来表示,
7.inet_interfaces
inet_interfaces 参数指定postfix系统监听的网络接口。缺省地,postfix监听
所有的网络接口。如果你的postfix运行在一个虚拟的ip地址上,则必须指定其监听的地址。
4.3 postfix的uce(unsolicited commercial email)控制
所谓uce控制就是指控制postfix接收或转发来自于什么地方的邮件。
缺省地,postfix转发符合以下条件的邮件:
* 来自客户端ip地址符合$mynetworks的邮件。
* 来自客户端主机名符合$relay_domains及其子域的邮件。
* 目的地为$relay_domains及其子域的邮件。
缺省地,postfix接受符合以下条件的邮件:
* 目的地为$inet_interfaces的邮件。
* 目的地为$mydestination的邮件。
* 目的地为$virtual_maps的邮件。
不过我们也能通过下面的规则来实现更强大的控制功能。
1. 信头过滤
通过header_checks参数限制接收邮件的信头的格式,如果符合指定的格式,则拒绝接收该邮件。能指定一个或多个查询列表,如果新邮件的信头符合列表中的某一项则拒绝该接收邮件。
2.客户端主机名/地址限制
通过smtpd_client_restrictions参数限制能向postfix发起smtp 连接的客户端的主机名或ip地址。能指定一个或多个参数值,中间用逗号隔开。限制规则是按照查询的顺序进行的,第一条符合条件的规则被执行。
3. 是否请求helo命令
能通过smtpd_helo_required参数指定客户端在smtp会话的开始是否发
送一个helo命令。你能指定该参数的值为yes或no。
4. helo主机名限制
能通过smtpd_helo_restrictions参数指定客户端在执行helo命令时发送
给postfix的主机名。缺省地,postfix接收客户端发送的任意形式的主机名。能指定一个或多个参数值,中间用逗号隔开。限制规则是按照查询的顺序进行的,第一条符合条件的规则被执行。
5. rfc 821信头限制
rfc 821对邮件的信头做了严格的规定,不过广泛使用的sendmail并不支
持该规定,所以对于该参数我们只能说不,
6. 通过发件人地址进行限制
能用smtpd_sender_restrictions参数通过发件人在执行mail from命令时提供的地址进行限制。能指定一个或多个参数值,中间用逗号隔开。限制规则是按照查询的顺序进行的,第一条符合条件的规则被执行。
reject_unknown_sender_domain:如果mail from命令提供的主机名在dns中没有相应的a 或 mx 记录则拒绝该客户端的连接请求。能用unknown_address_reject_code参数指定返回给客户机的错误代码(缺省为450)。
check_sender_access maptype:mapname:根据mail from命令提供的主机名、父域搜索access数据库。如果搜索的结果为reject 或 "[45]xx text" 则拒绝该客户端的连接请求;如果搜索的结果为ok、relay 或数字则接受该客户端的连接请求。能用access_map_reject_code参数指定返回给客户机的错误代码(缺省为554)。能通过该参数过滤来自某些不受欢迎的发件人的邮件。
reject_non_fqdn_sender:如果mail from命令提供的主机名不是rfc规定的完整的域名则拒绝客户端的连接请求。能用non_fqdn_reject_code 参数指定返回给客户机的错误代码(缺省为504)。
缺省地,postfix接受来自所有发件人的邮件。
7. 通过收件人地址进行过滤
能用smtpd_recipient_restrictions参数通过发件人在执行rcpt to命令
时提供的地址进行限制。缺省值为:
smtpd_recipient_restrictions = permit_mynetworks, check_relay_domains
能指定一个或多个参数值,中间用逗号隔开。限制规则是按照查询的顺序
进行的,第一条符合条件的规则被执行。可用的规则有:
check_relay_domains:如果符合以下的条件,则接受smtp连接请求,否则拒绝该连接,能用relay_domains_reject_code 参数指定返回给客户机的错误代码(缺省为504)。
* 客户端主机名符合$relay_domains及其子域
* 目的地为$inet_interfaces、$mydestination或$virtual_maps
permit_auth_destination:不管客户端的主机名,只要符合以下的条件,就
接受smtp连接请求:
* 解析后的目标地址符合$relay_domains及其子域
* 解析后的目标地址符合$inet_interfaces、$mydestination或$virtual_maps
reject_unauth_destination:不管客户端的主机名,只要符合以下的条件,
就拒绝该客户端smtp连接请求:
* 解析后的目标地址符合$relay_domains及其子域
* 解析后的目标地址符合$inet_interfaces、$mydestination或$virtual_maps
check_recipient_access:根据解析后的目标地址、父域搜索access数据库。如果搜索的结果为reject 或 "[45]xx text" 则拒绝该客户端的连接请求;如果搜索的结果为ok、relay 或数字则接受该客户端的连接请求。能用access_map_reject_code参数指定返回给客户机的错误代码(缺省为554)。
reject_unknown_recipient_domain:如果收件人的邮件地址在dns中没有相应的a 或 mx 记录则拒绝该客户端的连接请求。能用unknown_address_reject_code参数指定返回给客户机的错误代码(缺省为450)。
reject_non_fqdn_recipient:如果发件人在执行rcpt to命令时提供的地址
不是完整的域名则拒绝其smtp连接请求。能用the non_fqdn_reject_code参数指定返回给客户机的错误代码(缺省为504)。