FreeBSD 7-STABLE amd64 job record

来自开放百科 - 灰狐
跳转到: 导航, 搜索

最近接到任务,要为ISP的商务楼提供一台通用设备,放在大楼机房,提供以下服务:

  • 1、大楼宽带接入
  • 2、用户带宽管理
  • 3、静态路由
  • 4、用户流量监控
  • 5、邮件服务
  • 6、WEB磁盘服务
  • 7、WEB邮件服务
  • 8、反垃圾邮件
  • 9、DNS缓存和授权

拿到一台机器,具体配置如下:

CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 5000+ (2605.56-MHz K8-class CPU)
usable memory = 4279980032 (4081 MB)
em0: <Intel(R) PRO/1000 Network Connection Version - 6.7.3> port 0xef00-0xef1f mem 0xfdce0000-0xfdcfffff,0xfdcc0000-0xfdcdffff  irq 18 at device 0.0 on pci1
em1: <Intel(R) PRO/1000 Network Connection Version - 6.7.3> port 0xdf00-0xdf1f mem 0xfdee0000-0xfdefffff,0xfdec0000-0xfdedffff irq 19 at device 0.0 on pci2
fxp0: <Intel 82558 Pro/100 Ethernet> port 0xcf00-0xcf1f mem 0xfd8ff000-0xfd8fffff,0xfda00000-0xfdafffff irq 20 at device 4.0 on pci4
fxp1: <Intel 82558 Pro/100 Ethernet> port 0xce00-0xce1f mem 0xfd8fe000-0xfd8fefff,0xfd900000-0xfd9fffff irq 21 at device 5.0 on  pci4
ad0: 499MB <PQI IDE DiskOnModule 060729DA> at ata0-master WDMA2
ad4: 476938MB <Seagate ST3500320AS SD15> at ata2-master SATA300
ad6: 476940MB <Seagate ST3500320AS SD15> at ata3-master SATA300
ad8: 476940MB <Seagate ST3500320AS SD15> at ata4-master SATA300
ad10: 476940MB <Seagate ST3500320AS SD15> at ata5-master SATA300


安装系统:

=

FreeBSD 7.0-RELEASE amd64

这个机器用光盘启动会出现BTX错误,于是随便找了台酷睿2的机器把mini系统装在ad0上,分区如下:

/dev/ad0s1a on / (ufs, local, fsid 8ffe38491c7dd7c4)

注意,没有分配任何SWAP,现在内存便宜,随时加!

最小化安装系统:

router# df
Filesystem  1K-blocks    Used      Avail Capacity  Mounted on
data/root   1427457408  18816 1427438592     0%    /
devfs                1      1          0   100%    /dev

接下来做raidz:

router# glabel label disk1 /dev/ad4
router# glabel label disk2 /dev/ad6
router# glabel label disk3 /dev/ad8
router# glabel label disk4 /dev/ad10

glabel给硬盘打上标签以后有个好处,即后续的磁盘存取使用逻辑名称,跟物理连接无关。

router# kldload zfs
router# zpool create data raidz /dev/label/disk[1-4]
router# zpool status
 pool: data
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM

data             ONLINE       0     0     0
raidz1         ONLINE       0     0     0
  label/disk1  ONLINE       0     0     0
  label/disk2  ONLINE       0     0     0
  label/disk3  ONLINE       0     0     0
  label/disk4  ONLINE       0     0     0
errors: No known data errors
router# df -h
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/ad0s1a    484M    328M    117M    74%    /
devfs          1.0K    1.0K      0B   100%    /dev
data           1.3T      0B    1.3T     0%    /data

准备好了存储就可以把大部份系统移植到zfs里面去,留个/boot放在ufs上启动(FreeBSD Bootloader不能访问zfs),zfs的COW抗断电非常不错,ufs上面的内核只读启动,也很安全:

router# zfs set mountpoint=none data
router# zfs create data/root
router# zfs create data/usr
router# zfs create data/var
router# zfs create data/tmp
router# zfs set mountpoint=/data data/root
router# zfs set mountpoint=/data/usr data/usr
router# zfs set mountpoint=/data/var data/var
router# zfs set mountpoint=/data/tmp data/tmp
router# echo 'zfs_enable="YES"' >> /etc/rc.conf
router# find -x / | cpio -pmd /data
router# rm -rf /data/boot
router# mkdir /data/bootdir
router# cd /data
router# ln -s bootdir/boot boot
router# echo 'zfs_load="YES"' >> /boot/loader.conf
router# echo 'vfs.root.mountfrom="zfs:data/root"' >> /boot/loader.conf

改一下/data/etc/fstab,改到新的boot上:

/dev/ad0s1a             /bootdir        ufs     rw              1       1
router# zfs set mountpoint=/tmp data/tmp
router# zfs set mountpoint=/usr data/usr
router# zfs set mountpoint=/var data/var
router# cd /
router# zfs set mountpoint=legacy data/root

好了,基本系统就完成了,看看现在的存储结构:

router# df -h
Filesystem     Size    Used   Avail Capacity  Mounted on
data/root      1.3T     18M    1.3T     0%    /
devfs          1.0K    1.0K      0B   100%    /dev
/dev/ad0s1a    484M    328M    117M    74%    /bootdir
data/tmp       1.3T      0B    1.3T     0%    /tmp
data/usr       1.3T    136M    1.3T     0%    /usr
data/var       1.3T    256K    1.3T     0%    /var
router# zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
data        155M  1.33T  26.9K  none
data/root  18.4M  1.33T  18.4M  legacy
data/tmp   32.9K  1.33T  32.9K  /tmp
data/usr    136M  1.33T   136M  /usr
data/var    316K  1.33T   316K  /var

zfs在FreeBSD7.0上还是需要微调,缺省的参数会在密集IO操作时导致内核崩溃(做NFS测试的时候很容易就碰上了)!

router# echo 'vm.kmem_size_max="1073741824"' >> /boot/loader.conf
router# echo 'vm.kmem_size="1073741824"' >> /boot/loader.conf

下面这些东东扔进/etc/rc.conf:

dumpdev="NO" //不用SWAP设备
fsck_y_enable="YES"
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
update_motd="NO"
ntpdate_enable="YES"
ntpd_enable="YES"

重启系统,一切OK!

系统及内核更新:

=

重建世界*_*:

router# vi /usr/share/examples/cvsup/stable-supfile
*default host=cvsup.jp.FreeBSD.org //选个快点的镜像就行了,其他不用动
router# cd /usr/share/examples/cvsup
router# csup -g -L 2 stable-supfile //csup已经内置在base系统里了,不再需要cvsup
router# cd /usr/src
router# make buildworld
router# cd /usr/src/sys/amd64/conf
router# cp GENERIC GENERIC.orig
router# vi GENERIC
router# diff GENERIC GENERIC.orig
27c27
< #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
---
> makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
32c32
< #options INET6 # IPv6 communications protocols
---
> options INET6 # IPv6 communications protocols
310,330d309
<
< # PF support
< device          pf
< device          pflog
< device          pfsync
< options         ALTQ
< options         ALTQ_CBQ        # Class Bases Queuing (CBQ)
< options         ALTQ_RED        # Random Early Detection (RED)
< options         ALTQ_RIO        # RED In/Out
< options         ALTQ_HFSC       # Hierarchical Packet Scheduler (HFSC)
< options         ALTQ_PRIQ       # Priority Queuing (PRIQ)
< options         ALTQ_NOPCC      # Required for SMP build
<
< # vlan support
< device          vlan            #VLAN support (needs miibus)
<
< # Network Performance
< options         PANIC_REBOOT_WAIT_TIME=0
< options         DEVICE_POLLING
< options         HZ=2000
< options         IPSTEALTH

网卡全是Intel的,支持polling,ALTQ给VLAN用户做QoS,另外就是关掉了IPv6。别忘了把定制的GENERIC做个备份,省得下次同步源码的时候给覆盖了。

router# cp GENERIC GENERIC.20081210
router# cd /usr/src
router# make buildkernel
router# make installkernel
router# shutdown -r now
router# mergemaster -p
router# cd /usr/src
router# make installworld
router# mergemaster
router# reboot

世界改造完成!

到这里就可以把/boot设成只读了:

router# cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/ad0s1a /bootdir ufs ro 1 1
router# mount
data/root on / (zfs, local)
devfs on /dev (devfs, local)
/dev/ad0s1a on /bootdir (ufs, local, read-only)
data/opt on /opt (zfs, local)
data/tmp on /tmp (zfs, local)
data/usr on /usr (zfs, local)
data/var on /var (zfs, local)

安装应用软件:

=
router# cd /usr/share/examples/cvsup
router# vi ports-supfile
*default host=cvsup.jp.FreeBSD.org //选个快点的镜像
router# csup -g -L 2 ports-supfile
router# make index

在编译所有软件以前,先编辑一下 /etc/make.conf,我的很简单:

BATCH=yes
MASTER_SITE_BACKUP?= \
ftp://ftp.jp.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR}/\
MASTER_SITE_OVERRIDE?= ${MASTER_SITE_BACKUP}

后面会个别使用make config,否则的话全部安静安装。

第一部分:接入服务

1、 postgresql

router# cd /usr/ports/databases/postgresql83-server
router# make install clean

有几个地方需要注意:

/usr/local/etc/periodic/daily/502.pgsql 做vacuum和backup的模板
 options         SYSVSHM
 options         SYSVSEM
 options         SYSVMSG
 options         SHMMAXPGS=65536
 options         SEMMNI=40
 options         SEMMNS=240
 options         SEMUME=40
 options         SEMMNU=120

这一堆是高并发的时候可能需要调整的一些内核参数。

/usr/local/share/postgresql/odbc.sql 如果有ODBC连接的需求,需要运行一下这个。

初始化数据库:

router# echo 'postgresql_enable="YES"' >> /etc/rc.conf
router# /usr/local/etc/rc.d/postgresql initdb
router# /usr/local/etc/rc.d/postgresql start
router# su - pgsql -c 'createuser sysadm' //pgsql是postgresql的UNIX系统帐户,sysadm是postgresql内部的数据库帐户
router# su - pgsql -c 'createdb -O sysadm kydb' //给sysadm建个库叫kydb
router# psql kydb sysadm //以后就这样在命令行登录我们的库进行管理

当然别忘了修改我们的数据库登录密码:

kydb=> ALTER USER sysadm ENCRYPTED PASSWORD '123456';

改完密码以调整一下pg_hba.conf,然后重启一下:

pg_hba.conf文件里面屏蔽ipv6,然后unix socket和ipv4的连接开启md5。

# "local" is for Unix domain socket connections only
local   all         all                               md5
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               reject
router# /usr/local/etc/rc.d/postgresql restart

2、freeradius

router# cd /usr/ports/net/freeradius2
router# make config
[X] USER          Run as user freeradius, group freeradius
[X] PGSQL         With PostgreSQL database support
router# make install clean

配置FreeRadius:

第一步,/usr/local/etc/raddb/clients.conf,认证客户端配置,这一步建立一个客户端连接,所有需要使用AAA服务的软件通过这个客户端获取AAA 认证信息:

client localhost {
ipaddr = 127.0.0.1
secret = testing123
require_message_authenticator = no
nastype = other
}

第二步,/usr/local/etc/raddb/dictionary,PPPoE服务我用的是mpd,需要加上mpd的字典:

$INCLUDE /usr/local/share/freeradius/dictionary
$INCLUDE /usr/local/share/freeradius/dictionary.mpd

dictionary.mpd 在mpd的源码包里面,可以先把mpd解开拿过来用:

router# cd /usr/ports/net/mpd5
router# make extract
router# cp work/mpd-5.2/conf/dictionary.mpd /usr/local/share/freeradius/

第三步,/usr/local/etc/raddb/radiusd.conf,这个是主要进程配置,但是很多细节配置,例如数据库连接配置等都独立到各自文件了,所以这里很简单,基本上没有任何改动:

prefix = /usr/local
exec_prefix = ${prefix}
sysconfdir = ${prefix}/etc
localstatedir = /var
sbindir = ${exec_prefix}/sbin
logdir = /var/log
raddbdir = ${sysconfdir}/raddb
radacctdir = ${logdir}/radacct
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/radiusd
db_dir = $(raddbdir)
libdir = /usr/local/lib/freeradius-2.0.5
pidfile = ${run_dir}/radiusd.pid
user = freeradius
group = freeradius
max_request_time = 30
cleanup_delay = 5
max_requests = 1024
listen {
type = auth
ipaddr = 127.0.0.1
port = 0
}
listen {
type = acct
ipaddr = 127.0.0.1
port = 0
}
hostname_lookups = no
allow_core_dumps = no
regular_expressions = yes
extended_expressions = yes
log {
destination = files
file = ${logdir}/radius.log
syslog_facility = daemon
stripped_names = no
auth = no
auth_badpass = no
auth_goodpass = no
}
checkrad = ${sbindir}/checkrad
security {
max_attributes = 200
reject_delay = 1
status_server = yes
}
proxy_requests  = yes
$INCLUDE proxy.conf
$INCLUDE clients.conf
snmp = no
$INCLUDE snmp.conf
thread pool {
start_servers = 5
max_servers = 32
min_spare_servers = 3
max_spare_servers = 10
max_requests_per_server = 0
}
modules {
$INCLUDE ${confdir}/modules/
$INCLUDE eap.conf
$INCLUDE sql.conf
$INCLUDE sql/postgresql/counter.conf
}
instantiate {
exec
expr
expiration
logintime
}
$INCLUDE policy.conf
$INCLUDE sites-enabled/

第四步,/usr/local/etc/raddb/sql.conf,数据库连接配置和AAA访问的表定义:

sql {
database = "postgresql"
driver = "rlm_sql_${database}"
server = "localhost"
login = "sysadm"
password = "123456"
radius_db = "kydb"
acct_table1 = "radacct"
acct_table2 = "radacct"
postauth_table = "radpostauth"
authcheck_table = "radcheck"
authreply_table = "radreply"
groupcheck_table = "radgroupcheck"
groupreply_table = "radgroupreply"
usergroup_table = "radusergroup"
deletestalesessions = yes
sqltrace = no
sqltracefile = ${logdir}/sqltrace.sql
num_sql_socks = 5
connect_failure_retry_delay = 60
nas_table = "nas"
$INCLUDE sql/${database}/dialup.conf
}

第五步,主服务配置文件/usr/local/etc/raddb/sites-available/default

authorize {
preprocess
chap
mschap
suffix
sql
pap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
}
preacct {
preprocess
acct_unique
}
accounting {
sql
}
session {
sql
}
post-auth {
sql
Post-Auth-Type REJECT {
attr_filter.access_reject
}
}
pre-proxy {
}
post-proxy {
}

AAA 服务配置就OK了,freeradius网站有很不错的书可以参考。另外说一下,实际环境中我把所有的日志输出到/dev/console了。

第六步,部署AAA表:

router# cd /usr/local/etc/raddb/sql/postgresql
router# psql -U sysadm kydb < schema.sql

看一下都部署了哪些表:

kydb=> \dt
            List of relations
Schema |     Name      | Type  | Owner  
--------+---------------+-------+--------
public | radacct       | table | sysadm
public | radcheck      | table | sysadm 
public | radgroupcheck | table | sysadm
public | radgroupreply | table | sysadm
public | radpostauth   | table | sysadm
public | radreply      | table | sysadm
public | radusergroup  | table | sysadm
(7 rows)

OK!可以放认证数据了,我这里大多数用户接入使用PPPoE拨号方式,配合mpd的流量管理功能(ng_car),类似电信的ADSL拨号帐户,只是我们的传输不是ADSL而是标准以太网,在认证上跟ADSL没有什么分别,不过由于市面上各种各样的所谓“宽带路由器”chap握手兼容性太差,所以我这里使用pap,建立一个拨号帐号基本上分为组、用户和返回信息等配置。 先说说这些表的用途:

radacct:这个是帐务表,就是用户使用情况的记录,比较关心的是输入输出的字节数,后面给用户出mrtg图的地方会用
radcheck:用户的帐号密码表
radgroupcheck:组的认证信息表,没有用到
radgroupreply:组的返回信息,所有用户通用的配置可以扔在这里
radpostauth:记录认证行为的日志表
radreply:针对每用户的返回信息,带宽数据就在这里设定
radusergroup:用户和组的对应关系表

我们的应用要求比较简单,所有用户都在一个组,每个用户拥有自己的带宽,因此我们的任务就是定制帐号密码和带宽而已。 首先建立组的返回信息:

kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Framed-Protocol', ':=', 'PPP');

INSERT 0 1

kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Service-Type', ':=', 'Framed-User');

INSERT 0 1

kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Framed-Compression', ':=', 'Van-Jacobsen-TCP-IP');
INSERT 0 1

别问我那些attributes是什么意思,这个还是自己老老实实看mpd的手册。 开个用户 “test”,分配给他上行128KBps和下行256KBps的带宽,这样就可以了:

kydb=> INSERT INTO radusergroup (username, groupname) VALUES ('test', 'PPPoE');

INSERT 0 1 //先把test加入PPPoE组

kydb=> INSERT INTO radcheck (username, attribute, op, value) VALUES ('test', 'Cleartext-Password', ':=', 'test123');

INSERT 0 1 //建立test的认证帐号和密码

kydb=> INSERT INTO radreply (username, attribute, op, value) VALUES ('test', 'mpd-limit', '+=', 'in#1=all rate-limit 128000 150000 300000');
INSERT 0 1 //上行带宽
kydb=> INSERT INTO radreply (username, attribute, op, value) VALUES ('test', 'mpd-limit', '+=', 'out#1=all rate-limit 256000 150000 300000');
INSERT 0 1 //下行带宽

然后启动AAA:

router# radiusd -X //这样会进入调试模式,所有模块加载的过程都能看见,认证的过程也能看见,找问题比较方便。
router# radtest test test123 localhost 10 testing123
Sending Access-Request of id 156 to 127.0.0.1 port 1812
User-Name = "test"
User-Password = "test123"
NAS-IP-Address = 172.18.30.10
NAS-Port = 10
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=156, length=135
mpd-limit = "in#1=all rate-limit 128000 150000 300000"
mpd-limit = "out#1=all rate-limit 256000 150000 300000"
Framed-Protocol = PPP
Service-Type = Framed-User
Framed-Compression = Van-Jacobson-TCP-IP

rad_recv就是认证成功以后得到的返回信息。 如果出错,比如我们密码错了:

router# radtest test 123 localhost 10 testing123
Sending Access-Request of id 167 to 127.0.0.1 port 1812
User-Name = "test"
User-Password = "123"
NAS-IP-Address = 172.18.30.10
NAS-Port = 10
rad_recv: Access-Reject packet from host 127.0.0.1 port 1812, id=167, length=20

我们被reject了,AAA控制台上这样显示:

auth: type "PAP"
+- entering group PAP
rlm_pap: login attempt with password "123"
rlm_pap: Using clear text password "test123"
rlm_pap: Passwords don't match
++[pap] returns reject

好了,AAA安装配置到此结束,可以正式启用了:

router# echo 'radiusd_enable="YES"' >> /etc/rc.conf
router# touch /var/log/radius.log
router# chown freeradius:freeradius /var/log/radius.log
router# /usr/local/etc/rc.d/radiusd start
router# sockstat -l
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
freeradiusradiusd   3518  10 udp4   127.0.0.1:1812        *:*
freeradiusradiusd   3518  11 udp4   127.0.0.1:1813        *:*
freeradiusradiusd   3518  12 udp4   127.0.0.1:1814        *:*
pgsql    postgres   2425  4  tcp4   127.0.0.1:5432        *:*
pgsql    postgres   2425  5  stream /tmp/.s.PGSQL.5432
root     sshd       1067  3  tcp4   *:6789                *:*
root     ntpd       1009  20 udp4   *:123                 *:*
root     ntpd       1009  21 udp4   172.18.30.210:123     *:*
root     ntpd       1009  22 udp4   192.168.1.1:123       *:*
root     ntpd       1009  23 udp4   127.0.0.1:123         *:*
root     syslogd    916   4  dgram  /var/run/log
root     syslogd    916   5  dgram  /var/run/logpriv
root     syslogd    916   6  udp4   *:514                 *:*
root     devd       858   4  stream /var/run/devd.pipe

3、 mpd

mpd 启用流量计数需要安装ng_ipacct,安装比较麻烦,首先编译好的模块要写入/boot,因此要临时把/boot挂载成rw,另外需要内核源码,我们前面改造过世界:-),该有的都有了:

router# cd /usr/ports/net-mgmt/ng_ipacct
router# make install clean

这是/usr/local/etc /ng_ipacct.conf,我这里并没有修改缺省配置文件,mpd需要使用ng_ipacct模块,我们需要的是那个模块,不需要启动 ng_ipacct进程。

ng_ipacct_modules_load="YES"
ng_ipacct_modules_list="netgraph ng_ether ng_ipacct"
ng_ipacct_default_ether_start='
mkpeer %%iface%%: tee lower right
name %%iface%%:lower %%iface%%_tee
connect %%iface%%: lower upper left
mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_ip_acct
connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'
ng_ipacct_default_ether_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_tee:
shutdown %%iface%%:
'
ng_ipacct_bpf_ether_start='
mkpeer %%iface%%: tee lower right
name %%iface%%:lower %%iface%%_tee
connect %%iface%%: lower upper left
mkpeer %%iface%%_tee: bpf right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_bpf
connect %%iface%%_tee: right2left left2right %%iface%%_out
mkpeer %%iface%%_bpf: ipacct %%iface%%_match_in %%iface%%_in
name %%iface%%_bpf:%%iface%%_match_in %%iface%%_ip_acct
connect %%iface%%_bpf: %%iface%%_ip_acct: %%iface%%_match_out %%iface%%_out
'
ng_ipacct_bpf_ether_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_bpf:
shutdown %%iface%%_tee:
shutdown %%iface%%:
'
ng_ipacct_xl0_start=${ng_ipacct_default_ether_start}
ng_ipacct_xl0_stop=${ng_ipacct_default_ether_stop}
ng_ipacct_xl0_checkpoint_script="path/to/your/script --checkpoint-and-save xl0"
ng_ipacct_cx0_dlt="RAW"
ng_ipacct_cx0_start='
mkpeer %%iface%%: cisco rawdata downstream
name %%iface%%:rawdata %%iface%%_hdlc
mkpeer %%iface%%_hdlc: tee inet left
name %%iface%%_hdlc:inet %%iface%%_tee
mkpeer %%iface%%_tee: iface right inet
mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_ip_acct
connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'
ng_ipacct_cx0_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_tee:
shutdown %%iface%%_hdlc:
'
ng_ipacct_vpn0_dlt="RAW"
ng_ipacct_vpn0_start='
mkpeer ipacct dummy dummy
name .:dummy %%iface%%_ip_acct
mkpeer %%iface%%_ip_acct: ksocket  %%iface%%_in inet/raw/divert
name %%iface%%_ip_acct:%%iface%%_in  ks_%%iface%%_in
msg ks_%%iface%%_in:  bind inet/0.0.0.0:4001
mkpeer %%iface%%_ip_acct: ksocket %%iface%%_out inet/raw/divert
name %%iface%%_ip_acct:%%iface%%_out ks_%%iface%%_out
msg ks_%%iface%%_out: bind inet/0.0.0.0:4002
rmhook .:dummy
'
ng_ipacct_vpn0_stop='
shutdown %%iface%%_ip_acct:
'
ng_ipacct_xl0_start=${ng_ipacct_bpf_ether_start}
ng_ipacct_xl0_stop=${ng_ipacct_bpf_ether_stop}
ng_ipacct_xl0_checkpoint_script="path/to/your/script --checkpoint-and-save xl0"
ng_ipacct_xl0_afterstart_script="path/to/your/script --load-bpf-filters xl0"
ng_ipacct_ks_start='
mkpeer ipacct dummy dummy
name .:dummy %%iface%%_ip_acct
mkpeer %%iface%%_ip_acct: tee  %%iface%%_in left2right
name   %%iface%%_ip_acct:%%iface%%_in  %%iface%%_tee_in
mkpeer %%iface%%_ip_acct: tee  %%iface%%_out left2right
name   %%iface%%_ip_acct:%%iface%%_out %%iface%%_tee_out
mkpeer %%iface%%_tee_in:  echo right in
name   %%iface%%_tee_in:right  %%iface%%_echo_in
mkpeer %%iface%%_tee_out: echo right out
name   %%iface%%_tee_out:right %%iface%%_echo_out
mkpeer %%iface%%_tee_in: ksocket  left inet/raw/divert
name   %%iface%%_tee_in:left  %%iface%%_ks_in
msg    %%iface%%_ks_in:  bind inet/0.0.0.0:4001
mkpeer %%iface%%_tee_out: ksocket left inet/raw/divert
name   %%iface%%_tee_out:left %%iface%%_ks_out
msg    %%iface%%_ks_out: bind inet/0.0.0.0:4002
rmhook .:dummy
'
ng_ipacct_ks_stop='
shutdown %%iface%%_ks_in:
shutdown %%iface%%_ks_out:
shutdown %%iface%%_tee_in:
shutdown %%iface%%_tee_out:
'
ng_ipacct_ks_checkpoint_script="path/to/your/script --checkpoint-and-save ks"
router# cd /usr/ports/net/mpd5
router# make config
[X] NG_IPACCT  Use ng_ipacct kernel module from port
router# make install clean
router# cd /usr/local/etc/mpd5
router# cp mpd.conf.sample mpd.conf
router# cp mpd.script.sample mpd.script
router# cp mpd.secret.sample mpd.secret

接下来就是mpd.conf的具体配置,其他两个文件没有用到:

startup:
set netflow peer 127.0.0.1 1813
set user admin 123456 admin
set user operator 123456 operator
set user user 123456 user
set console open

default:

load pppoe_server

pppoe_server:

create bundle template B
set ippool add pool 10.0.0.100 10.0.0.200
set iface enable netflow-in
set iface enable netflow-out
set iface enable ipacct
set iface enable proxy-arp
set ipcp ranges 10.0.0.1/32 ippool pool
set ipcp dns 202.96.209.5 202.96.209.133

create link template common pppoe

set link enable pap
set link disable chap
set link enable multilink
set link action bundle B
load radius

create link template fxp0 common

set link max-children 1000
set pppoe iface fxp0
set link enable incoming

radius:

set radius server 127.0.0.1 testing123 1812 1813
set radius retries 3
set radius timeout 3
set radius me 127.0.0.1
set auth max-logins 1
set auth acct-update 300
set auth enable radius-auth
set auth enable radius-acct
set radius enable message-authentic

重点的参数理解一下:

set netflow peer 127.0.0.1 1813 //发送累计流量数据给AAA
load pppoe_server //我们目前仅仅启用了pppoe拨入服务
set ippool add pool 10.0.0.100 10.0.0.200 //拨号用户地址池,需要使用静态公网地址的用户可以做在AAA的用户返回信息里面,AAA返回信息优先
set iface enable netflow-in //开启in流量统计
set iface enable netflow-out //开启out流量统计
set iface enable ipacct //开启ipacct设备用于统计
set radius server 127.0.0.1 aaa123 1812 1813 //连接AAA的信息,1812是认证,1813是记账
set link disable chap pap eap
set link enable pap //只启用pap握手
create link template fxp0 common //在fxp0上响应拨号请求
set link max-children 500 //允许最多500人拨号
set pppoe iface fxp0 //pppoe信号在fxp0上发送
set link enable incoming //允许拨入
set auth max-logins 1 //每个帐户只能单人使用

现在正式启用拨号进程:

router# echo 'mpd_enable="YES"' >> /etc/rc.conf
router# echo 'ng_ipacct_enable="YES"' >> /etc/rc.conf
router# /usr/local/etc/rc.d/mpd5 start
Starting mpd5.

router# sockstat -l

USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
root     mpd5       8369  16 tcp4   127.0.0.1:5005        *:*
freeradiusradiusd   8362  10 udp4   127.0.0.1:1812        *:*
freeradiusradiusd   8362  11 udp4   127.0.0.1:1813        *:*
freeradiusradiusd   8362  12 udp4   127.0.0.1:1814        *:*
root     sshd       1084  3  tcp4   *:6789                *:*
pgsql    postgres   1046  3  tcp4   127.0.0.1:5432        *:*
pgsql    postgres   1046  4  stream /tmp/.s.PGSQL.5432
root     ntpd       1015  20 udp4   *:123                 *:*
root     ntpd       1015  21 udp4   172.18.30.210:123     *:*
root     ntpd       1015  22 udp4   192.168.1.1:123       *:*
root     ntpd       1015  23 udp4   127.0.0.1:123         *:*
root     syslogd    916   4  dgram  /var/run/log
root     syslogd    916   5  dgram  /var/run/logpriv
root     syslogd    916   6  udp4   *:514                 *:*
root     devd       858   4  stream /var/run/devd.pipe

router# kldstat

Id Refs Address            Size     Name
1   18 0xffffffff80100000 b7c658   kernel
2    1 0xffffffff80c7d000 f5ae8    zfs.ko
3    2 0xffffffff80d73000 2b98     opensolaris.ko
4    1 0xffffffffdb172000 199e     ng_socket.ko
5   13 0xffffffffdb174000 8e1c     netgraph.ko
6    1 0xffffffffdb17d000 1813     ng_mppc.ko
7    1 0xffffffffdb17f000 218      rc4.ko
8    1 0xffffffffdb113000 128e     ng_ether.ko
9    1 0xffffffffdb185000 30a6     ng_pppoe.ko
10    1 0xffffffffdb115000 15f6     ng_ipacct.ko
11    1 0xffffffffdb117000 a86      ng_tee.ko
12    1 0xffffffffdb1f7000 138e     ng_iface.ko
13    1 0xffffffffdb1f9000 4586     ng_ppp.ko
14    1 0xffffffffdb203000 24c4     ng_netflow.ko
15    1 0xffffffffdb206000 200e     ng_ksocket.ko
16    1 0xffffffffdb209000 1b2c     ng_bpf.ko
17    1 0xffffffffdb20b000 13a6     ng_car.ko
18    1 0xffffffffdb1f2000 1e8c     ng_vjc.ko

PPPoE 接入服务到此配置完成,用户可以通过以太网连接建立PPPoE拨号上网,每个用户的带宽在建立帐号的时候就可以指定,如果用户到期可以通过mpd的控制台先拆除链路,然后删除用户帐号即可,我这是用的笨办法,聪明一点就做在AAA上,分配给用户帐号有效期。实际使用中管理帐号如果直接操作SQL语句比较烦人,我偷懒就写了一个C的管理工具,再懒一点用Perl也行,做成WEB方式管理我个人非常不喜欢。这部份有很大的扩展空间,例如如何分配给用户公网地址,如何路由,如何为用户出流量报告,如何加入无线接入,如何开启按流量计费,如何自动掐断用户链路等等,大部份内容需要很好地理解AAA的工作方式以及 mpd的工作方式,留在需要的时候继续研究,作为用户接入、带宽管理和物理隔离这些内容已经工作得很好了。

静态路由:

有一部分大楼用户要求运营商直接分配公网地址(静态地址),我们采用VLAN加PF的组合,简单罗列一下生产环境的网络参数和PF配置我觉得就行了:

router# cat /etc/rc.conf
...
cloned_interfaces="vlan0"
ifconfig_vlan0="inet 123.123.123.193 netmask 255.255.255.252 vlan 2 vlandev fxp0"
...

router# cat /etc/pf.conf

# network interfaces
ext_if = "fxp1"
int_if = "fxp0"
lo_if = "lo0"
# tables
table <rfc1918> const { 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
# runtime options
set timeout { interval 3, frag 5 }
set timeout { tcp.first 20, tcp.opening 10, tcp.established 600 }
set timeout { tcp.closing 10, tcp.finwait 10, tcp.closed 10 }
set timeout { udp.first 10, udp.single 10, udp.multiple 60 }
set timeout { icmp.first 5, icmp.error 5 }
set timeout { other.first 10, other.single 10, other.multiple 30 }
set timeout { adaptive.start 0, adaptive.end 0 }
set limit { src-nodes 40000, states 40000, frags 10000 }
set optimization aggressive
set block-policy drop
set require-order yes
set fingerprints "/etc/pf.os"
set skip on $lo_if
# scrub
scrub in all
# set altq
altq on $ext_if bandwidth 4Mb cbq queue { ping-out, radmin-out, bulk-out }
queue ping-out bandwidth 400Kb priority 7 cbq ( borrow )
queue bulk-out bandwidth 3.6Mb priority 1 cbq ( default, red )
# set altq
altq on $int_if bandwidth 100Mb cbq queue { b2048, b1024, b512, other }
queue b2048 bandwidth 2Mb cbq ( red, ecn )
queue b1024 bandwidth 1Mb cbq ( red, ecn )
queue b512 bandwidth 1Mb cbq (  red, ecn )
queue other bandwidth 96Mb cbq ( default, red, ecn )
# nat for lan
nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if)
# anti-spoof
antispoof quick for $ext_if
block in quick on $ext_if from <rfc1918> to any
block out quick on $ext_if from any to <rfc1918>
# queuing
pass out quick on $ext_if inet proto icmp from any to any icmp-type echoreq queue ping-out
pass out quick on $ext_if inet proto { tcp udp } from any to any queue ( bulk-out, ping-out )
pass out quick on $int_if from any to 123.123.123.194 queue b2048
# default pass
pass quick all

在这个基础上再写个程序添加静态用户,基本上混合接入的平台就成了。我偷懒,没有写静态用户的管理程序,因为我觉得命令加配置文件已经足够简单了。只要交换机上配好VLAN,ifconfig一下,再加一条pf规则就搞定:

router# ifconfig vlan0 create
router# ifconfig vlan0 vlan 2 vlandev fxp0
router# ifconfig vlan0 inet 123.123.123.193 netmask 255.255.255.252

pf 规则上面已经给出,123.123.123.193是我的地址,123.123.123.194是用户地址,我们在123.123.123.192/30 上互联,静态用户之间互不干扰,就是有点浪费地址资源。

用户流量监控使用mrtg,具体就是需要自己写个数据采集的程序,这个官网上有详细文档和数据格式定义,我是直接拿以前写好的过来用。如果不需要出图,我一般就用systat -if或者iptop简单看看,或者netstat也行(我们的用户不管是拨号还是静态地址都拥有唯一的Interface):

router# netstat -I ng0 -bn 1
           input          (ng0)           output
  packets  errs      bytes    packets  errs      bytes colls
       21     0       4704         15     0       2887     0
        8     0       1129         14     0       2949     0
        2     0        129          1     0         93     0
        1     0         40          2     0        248     0
        4     0        172          2     0        449     0
        0     0          0          0     0          0     0

最后看看到现在为止系统里装了哪些ports:

router# pkg_info

autoconf-2.62       Automatically configure source code on many Un*x platforms
autoconf-wrapper-20071109 Wrapper script for GNU autoconf
expat-2.0.1         XML 1.0 parser written in C
freeradius-2.0.5    A free RADIUS server implementation
gdbm-1.8.3_3        The GNU database manager
gettext-0.17_1      GNU gettext package
gmake-3.81_3        GNU version of 'make' utility
help2man-1.36.4_2   Automatically generating simple manual pages from program o
libiconv-1.11_1     A character set conversion library
libltdl-1.5.26      System independent dlopen wrapper
libpdel-0.5.3_4     Packet Design multi-purpose C library for embedded applicat
libtool-1.5.26      Generic shared library support script
m4-1.4.11,1         GNU m4
mpd-5.2             Multi-link PPP daemon based on netgraph(4)
ng_ipacct-20061223  Netgraph IP accounting
p5-gettext-1.05_2   Message handling functions
perl-5.8.8_1        Practical Extraction and Report Language
postgresql-client-8.3.5 PostgreSQL database (client)
postgresql-server-8.3.5 The most advanced open-source database available anywhere
python25-2.5.2_3    An interpreted object-oriented programming language

第二部分:邮件服务

邮件是个复杂的系统:-)

考虑到大楼用户的需求,必须提供:

POP3/POP3+SSL服务,IMAP /IMAP+SSL服务,反垃圾邮件支持,邮件附件病毒检测,WEB邮件服务,用户修改密码,多域名系统,每个域名分权管理,网络空间(博客),邮件存储限额,。。。

经验选择:

MTA:postfix
MDA:dovecot
POP3/POP3+SSL:dovecot
IMAP、IMAP+SSL:dovecot
antispam:dspam+postgrey
antivirus:clamav
WEB Mail:squirrel
blog:wordpress
Management:pending...

选择dspam是因为dspam不是基于“规则”,而是基于人工智能和机器学习,依靠用户行为和邮件内容判断垃圾邮件。因为所谓“垃圾邮件”本来就是非常个性化的概念,所以人工智能,而不是规则,才应该在这里大展拳脚!

squirrel是HTML4标准的WEB邮件系统,最强的就是兼容!没有讨厌的JS,也没有讨厌的Ajax,以后在lynx里面收信也没问题了!但是要翻译中文界面,囧。。。

博客?本意是提供网络存储,后来觉得干嘛不干脆上个博客?用户可以快速存取大楼服务器,上传照片,文件,书。。。没事还能写点东西,多好。

1、 dovecot

router# cd /usr/ports/mail/dovecot
router# make config
[X] KQUEUE       kqueue(2) support
[X] SSL          SSL support
[X] POP3         POP3 support
[X] LDA          LDA support
[X] PGSQL        PostgreSQL support
router# make install clean
router# echo 'dovecot_enable="YES"' >> /etc/rc.conf

2、postfix

router# cd /usr/ports/mail/postfix
router# make config
[X] PCRE      Perl Compatible Regular Expressions
[X] DOVECOT   Dovecot SASL authentication method
[X] TLS       Enable SSL and TLS support
[X] PGSQL     PostgreSQL maps (choose with DEFAULT_PGSQL_VER)
router# make install clean
router# echo 'postfix_enable="YES"' >> /etc/rc.conf

首先屏蔽系统自带的sendmail:

/etc/rc.conf:
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
/etc/periodic.conf:
daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"

接下来需要利用mailwrapper为系统提供一个mailer,系统的某些例行任务需要一个mailer来向管理员发送邮件。

router# cd /etc/mail
router# cp mailer.conf mailer.conf.orig
router# sed -i .bak -e 's/libexec\/sendmail/local\/sbin/g' mailer
router# rm mailer.conf.bak

这是个好习惯,尽管前面我已经屏蔽了sendmail 的outbound,这样做保持了系统的完整性。

我们的邮件系统需要支持多域,因此所有的邮件用户都使用同一个系统帐号访问存储系统,现在就来建立这个虚拟的帐号和存储系统:

router# zfs create data/vmail
router# zfs set mountpoint=/vmail data/vmail
router# pw groupadd vmail -g 5000
router# pw useradd vmail -u 5000 -g vmail -d /data/vmail
router# chown -R vmail:vmail /vmail

/vmail 就是我们邮件存储的根目录,vmail就是邮件虚拟帐户。

我们的邮件系统需要提供TLS加密连接,但是我们没有条件使用商业CA提供数字签名,因此需要自己建立一个CA来做服务器证书的数字签名,SMTP和IMAP、POP3都需要这个证书:

router# cd /usr/local/etc
router# mkdir -p ssl/ketnet.com.cn/mail
router# mkdir -p ssl/ketnet.com.cn/mail/CA
router# mkdir -p ssl/ketnet.com.cn/mail/CA/private
router# mkdir -p ssl/ketnet.com.cn/mail/CA/certs
router# mkdir -p ssl/ketnet.com.cn/mail/CA/newcerts
router# mkdir -p ssl/ketnet.com.cn/mail/CA/crl
router# cd ssl/ketnet.com.cn/mail/CA
router# cp /etc/ssl/openssl.cnf openssl.my.cnf
router# chmod 0600 openssl.my.cnf
router# touch index.txt
router# echo '01' > serial
router# openssl req -config openssl.my.cnf -new -x509 -extensions v3_ca -keyout private/ca.key -out certs/ca.crt -days 3650
router# chmod 0400 private/ca.key

由于我们定制了证书的目录结构,因此必须要修改openssl的配置文件以满足我们的目录结构:

router# cp openssl.my.cnf openssl.my.cnf.orig

修改后的配置文件:

[ CA_default ]
dir             = .                     # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
new_certs_dir   = $dir/newcerts         # default place for new certs.
certificate     = $dir/certs/ca.crt     # The CA certificate
serial          = $dir/serial           # The current serial number
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/ca.key   # The private key
RANDFILE        = $dir/private/.rand    # private random number file
x509_extensions = usr_cert              # The extentions to add to the cert
name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options
default_days    = 3650                  # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = sha1                  # which md to use.
preserve        = no                    # keep passed DN ordering
policy          = policy_match

文件的其他部份保持原状。

需要SSL证书的进程可能会需要无人干预的重启,因此不能为证书的私钥加密,否则每次重启需要人工输入密码才能访问私钥,但是为了安全起见,这些私钥又不能被其他帐号访问,所以只能修改私钥的权限了:

router# openssl req -config openssl.my.cnf -new -nodes -keyout private/server.key -out server.csr
router# chown root private/server.key
router# chmod 0400 private/server.key
router# openssl ca -config openssl.my.cnf -policy policy_anything -out certs/server.crt -infiles server.csr
router# rm -f server.csr

验证我们的证书:

router# openssl x509 -subject -issuer -enddate -noout -in certs/server.crt
router# openssl x509 -in certs/server.crt -noout -text
router# openssl verify -purpose sslserver -CAfile certs/ca.crt certs/server.crt

仔细观察输出是否正确。

为了方便,证书有效期设置为10年!但是正式环境中应用时一般有效期设置为1年甚至更短时间,这里多说一句就是如何作废证书:

router# openssl ca -config openssl.my.cnf -revoke certs/server.crt
router# openssl ca -config openssl.my.cnf -gencrl -out crl/ca.crl

OK!证书制作到此为止。

前面已经创建了用于邮件系统的虚拟帐号和组,现在为虚拟帐号的后端引擎查找邮件用户对应的邮件目录提供查找表,也就是一系列的virtual_map表,postfix需要使用virtual后端引擎查找表验证用户的发信权限,dovecot需要这个表负责投递信件,postfixadmin需要这个表管理用户,postfix和dovecot只需要读权限,postfixadmin需要读写权限,我们的表存储在postgresql数据库内,表结构从postfixadmin里面生成,因为postfixadmin是php的代码,因此首先要把apache和php装好:

router# cd /usr/ports/www/apache22
router# make config
[X] PGSQL                 Enable PostgreSQL support for apr-dbd
[X] AUTHN_DBD             Enable mod_authn_dbd

除了缺省的配置选项(比较多,没有罗列)我们增加了对postgresql的认证模块,以后用来对一些受限访问的服务添加认证支持,另外请记住选上SSL!

router# make install clean
router# echo 'apache22_enable="YES"' >> /etc/rc.conf
router# cd /usr/ports/lang/php5
[X] APACHE     Build Apache module //增加的选项
router# make install clean
router# cd /usr/ports/lang/php5-extensions
router# make config
[X] PGSQL       PostgreSQL database support //增加的选项
[X] IMAP        IMAP support //增加的选项
[X] MBSTRING    multibyte string support //增加的选项
router# make install clean
router# cp httpd.conf httpd.conf.orig

把 postfixadmin装上,就顺便部署mail的数据库结构:

router# cd /usr/ports/mail/postfixadmin
router# make config
[X] PGSQL   PostgreSQL back-end (use pgsql PHP extension)

配置就选择了PGSQL。

router# cd /usr/local/www/postfixadmin
router# cp config.inc.php config.inc.php.orig

config.inc.php 是postfixadmin的配置文件,主要是修改数据库链接配置,修改的部份如下:

$CONF['configured'] = true;
$CONF['database_type'] = 'pgsql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'sysadm';
$CONF['database_password'] = '123456';
$CONF['database_name'] = 'kydb';

postfixadmin 通过WEB页面调用来创建管理数据库结构,apache我们已经装好了,php5的apache模块也已经装好了,apache的配置文件如下,并没有创建虚拟主机,这个留到最后全部工作完成了再统一定义不同的WEB应用对应的不同的虚拟主机,配置阶段就辛苦一点,直接用URL+目录来访问:

ServerRoot "/usr/local"
Listen 80
LoadModule authn_file_module libexec/apache22/mod_authn_file.so
LoadModule authn_dbm_module libexec/apache22/mod_authn_dbm.so
LoadModule authn_anon_module libexec/apache22/mod_authn_anon.so
LoadModule authn_dbd_module libexec/apache22/mod_authn_dbd.so
LoadModule authn_default_module libexec/apache22/mod_authn_default.so
LoadModule authn_alias_module libexec/apache22/mod_authn_alias.so
LoadModule authz_host_module libexec/apache22/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache22/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache22/mod_authz_user.so
LoadModule authz_dbm_module libexec/apache22/mod_authz_dbm.so
LoadModule authz_owner_module libexec/apache22/mod_authz_owner.so
LoadModule authz_default_module libexec/apache22/mod_authz_default.so
LoadModule auth_basic_module libexec/apache22/mod_auth_basic.so
LoadModule auth_digest_module libexec/apache22/mod_auth_digest.so
LoadModule file_cache_module libexec/apache22/mod_file_cache.so
LoadModule cache_module libexec/apache22/mod_cache.so
LoadModule disk_cache_module libexec/apache22/mod_disk_cache.so
LoadModule dumpio_module libexec/apache22/mod_dumpio.so
LoadModule include_module libexec/apache22/mod_include.so
LoadModule filter_module libexec/apache22/mod_filter.so
LoadModule charset_lite_module libexec/apache22/mod_charset_lite.so
LoadModule deflate_module libexec/apache22/mod_deflate.so
LoadModule log_config_module libexec/apache22/mod_log_config.so
LoadModule logio_module libexec/apache22/mod_logio.so
LoadModule env_module libexec/apache22/mod_env.so
LoadModule mime_magic_module libexec/apache22/mod_mime_magic.so
LoadModule cern_meta_module libexec/apache22/mod_cern_meta.so
LoadModule expires_module libexec/apache22/mod_expires.so
LoadModule headers_module libexec/apache22/mod_headers.so
LoadModule usertrack_module libexec/apache22/mod_usertrack.so
LoadModule unique_id_module libexec/apache22/mod_unique_id.so
LoadModule setenvif_module libexec/apache22/mod_setenvif.so
LoadModule version_module libexec/apache22/mod_version.so
LoadModule ssl_module libexec/apache22/mod_ssl.so
LoadModule mime_module libexec/apache22/mod_mime.so
LoadModule dav_module libexec/apache22/mod_dav.so
LoadModule status_module libexec/apache22/mod_status.so
LoadModule autoindex_module libexec/apache22/mod_autoindex.so
LoadModule asis_module libexec/apache22/mod_asis.so
LoadModule info_module libexec/apache22/mod_info.so
LoadModule cgi_module libexec/apache22/mod_cgi.so
LoadModule dav_fs_module libexec/apache22/mod_dav_fs.so
LoadModule vhost_alias_module libexec/apache22/mod_vhost_alias.so
LoadModule negotiation_module libexec/apache22/mod_negotiation.so
LoadModule dir_module libexec/apache22/mod_dir.so
LoadModule imagemap_module libexec/apache22/mod_imagemap.so
LoadModule actions_module libexec/apache22/mod_actions.so
LoadModule speling_module libexec/apache22/mod_speling.so
LoadModule userdir_module libexec/apache22/mod_userdir.so
LoadModule alias_module libexec/apache22/mod_alias.so
LoadModule rewrite_module libexec/apache22/mod_rewrite.so
LoadModule php5_module        libexec/apache22/libphp5.so
<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>
User www
Group www
</IfModule>
</IfModule>
ServerAdmin [email protected]
DocumentRoot "/usr/local/www"
<Directory />
   AllowOverride None
   Order deny,allow
   Deny from all
</Directory>
<Directory "/usr/local/www">
   Options Indexes FollowSymLinks
   AllowOverride None
   Order allow,deny
   Allow from all
</Directory>
<IfModule dir_module>
   DirectoryIndex index.html
</IfModule>
<FilesMatch "^\.ht">
   Order allow,deny
   Deny from all
   Satisfy All
</FilesMatch>
ErrorLog "/var/log/httpd-error.log"
LogLevel warn
<IfModule log_config_module>
   LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
   LogFormat "%h %l %u %t \"%r\" %>s %b" common
   <IfModule logio_module>
     LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
   </IfModule>
   CustomLog "/var/log/httpd-access.log" combined
</IfModule>
<IfModule alias_module>
   ScriptAlias /cgi-bin/ "/usr/local/www/cgi-bin/"
</IfModule>
<IfModule cgid_module>
</IfModule>
<Directory "/usr/local/www/cgi-bin">
   AllowOverride None
   Options None
   Order allow,deny
   Allow from all
</Directory>
DefaultType text/plain
<IfModule mime_module>
   TypesConfig etc/apache22/mime.types
   AddType application/x-compress .Z
   AddType application/x-gzip .gz .tgz
</IfModule>
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
<IfModule mod_php5.c>
   DirectoryIndex index.php index.html
   AddType application/x-httpd-php .php
   AddType application/x-httpd-php-source .phps
</IfModule>
Include etc/apache22/Includes/*.conf

router# /usr/local/etc/rc.d/apache22 start

router# sockstat -l

USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
www      httpd      73083 3  tcp4   *:80                  *:*
www      httpd      73076 3  tcp4   *:80                  *:*
www      httpd      73073 3  tcp4   *:80                  *:*
www      httpd      73072 3  tcp4   *:80                  *:*
www      httpd      73071 3  tcp4   *:80                  *:*
www      httpd      73070 3  tcp4   *:80                  *:*
www      httpd      73069 3  tcp4   *:80                  *:*
root     httpd      73067 3  tcp4   *:80                  *:*
root     sshd       1106  3  tcp4   *:6789                *:*
freeradiusradiusd   1077  10 udp4   127.0.0.1:1812        *:*
freeradiusradiusd   1077  11 udp4   127.0.0.1:1813        *:*
freeradiusradiusd   1077  12 udp4   127.0.0.1:1814        *:*
pgsql    postgres   1056  3  tcp4   127.0.0.1:5432        *:*
pgsql    postgres   1056  4  stream /tmp/.s.PGSQL.5432
root     ntpd       1024  20 udp4   *:123                 *:*
root     ntpd       1024  21 udp4   203.156.210.12:123    *:*
root     ntpd       1024  22 udp4   210.13.81.242:123     *:*
root     ntpd       1024  23 udp4   127.0.0.1:123         *:*
root     mpd5       992   16 tcp4   127.0.0.1:5005        *:*
root     syslogd    917   4  dgram  /var/run/log
root     syslogd    917   5  dgram  /var/run/logpriv
root     syslogd    917   6  udp4   *:514                 *:*
root     devd       859   4  stream /var/run/devd.pipe

从上可见,我们需要的运行postfixadmin的组件(apache+php+postgresql)都起来了,下面试试看:

http:// 服务器地址/postfixadmin/setup.php

稍等一会,这个setup.php会帮我们创建好数据库结构,如果没有错误,页面上会显示类似这样的一堆信息,表示安装成功,数据库表结构创建成功:

Postfix Admin Setup Checker

Running software:

PHP version 5.2.8

Apache/2.2.9 (FreeBSD) mod_ssl/2.2.9 OpenSSL/0.9.8e DAV/2 PHP/5.2.8 with Suhosin-Patch

Checking for dependencies:

Warning: Magic Quotes: ON (internal workaround used)
Depends on: presence config.inc.php - OK
Checking $CONF['configured'] - OK
Depends on: PostgreSQL - OK
Testing database connection - OK - pgsql://sysadm:xxxxx@localhost/kydb
Depends on: session - OK
Depends on: pcre - OK
Depends on: multibyte string - OK
Depends on: IMAP functions - OK
Everything seems fine... attempting to create/update database structure

Updating database:

old version: 0; target version: 397

updating to version 1 (all databases)...upgrade_1 done

updating to version 2 (PgSQL)... done

updating to version 4 (PgSQL)... done

updating to version 90 (all databases)... done

updating to version 344 (PgSQL)... done

接下来就是建立一个系统管理员帐号,这个帐号是一个 mail地址!建好帐号后页面显示:

Admin has been added! ([email protected])

You can now log in to Postfix Admin.

Make sure you delete this setup.php file! Also check the config.inc.php file for any settings that you might need to change!

到这里postfixadmin以及我们后面需要的数据库结构就完成了,别忘了按照提示删除setup.php这个文件,否则不能登录!

router# mv setup.php setup.php.disabled

之后就用下面的方式管理邮件帐号,postfixadmin可以指定域管理员管理自己域的帐号,普通用户可以登录修改帐号密码,也可以设定转发地址,不过 postfixadmin的功能也就仅限于此:

http://服务器地址/postfixadmin

一切就绪,可以配置SMTP服务了: postfix的配置相当灵活,需要仔细阅读手册,不过一般来说做虚拟域(类似apache的虚拟主机),要点不外乎以下几个:

  • 主机名
  • 主域名
  • 域名反向解析
  • SMTP发送认证
  • SMTP连接认证
  • 加密
  • 虚拟映射表
  • 投递代理

第一步先来看看主配置文件main.cf:

装载:http://blog.chinaunix.net/u2/64982/showart_1680687.html

Comment-32x32.png

<discussion>characters_max=300</discussion>

分享您的观点
个人工具
名字空间

变换
操作
导航
工具箱