FreeBSD 7-STABLE amd64 job record

来自开放百科 - 灰狐
(版本间的差异)
跳转到: 导航, 搜索
(以内容'最近接到任务,要为ISP的商务楼提供一台通用设备,放在大楼机房,提供以下服务: 1、大楼宽带接入 2、用户带宽管理 3、静态路...'创建新页面)
 
第1行: 第1行:
 
最近接到任务,要为ISP的商务楼提供一台通用设备,放在大楼机房,提供以下服务:
 
最近接到任务,要为ISP的商务楼提供一台通用设备,放在大楼机房,提供以下服务:
  
1、大楼宽带接入
+
*1、大楼宽带接入
2、用户带宽管理
+
*2、用户带宽管理
3、静态路由
+
*3、静态路由
4、用户流量监控
+
*4、用户流量监控
5、邮件服务
+
*5、邮件服务
6、WEB磁盘服务
+
*6、WEB磁盘服务
7、WEB邮件服务
+
*7、WEB邮件服务
8、反垃圾邮件
+
*8、反垃圾邮件
9、DNS缓存和授权
+
*9、DNS缓存和授权
  
 
拿到一台机器,具体配置如下:
 
拿到一台机器,具体配置如下:
  
CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 5000+ (2605.56-MHz K8-class CPU)
+
CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 5000+ (2605.56-MHz K8-class CPU)
usable memory = 4279980032 (4081 MB)
+
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
+
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
+
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
+
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
+
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
+
ad0: 499MB <PQI IDE DiskOnModule 060729DA> at ata0-master WDMA2
ad4: 476938MB <Seagate ST3500320AS SD15> at ata2-master SATA300
+
ad4: 476938MB <Seagate ST3500320AS SD15> at ata2-master SATA300
ad6: 476940MB <Seagate ST3500320AS SD15> at ata3-master SATA300
+
ad6: 476940MB <Seagate ST3500320AS SD15> at ata3-master SATA300
ad8: 476940MB <Seagate ST3500320AS SD15> at ata4-master SATA300
+
ad8: 476940MB <Seagate ST3500320AS SD15> at ata4-master SATA300
ad10: 476940MB <Seagate ST3500320AS SD15> at ata5-master SATA300
+
ad10: 476940MB <Seagate ST3500320AS SD15> at ata5-master SATA300
  
  
 
安装系统:
 
安装系统:
 +
 
=======
 
=======
 +
 
FreeBSD 7.0-RELEASE amd64
 
FreeBSD 7.0-RELEASE amd64
  
 
这个机器用光盘启动会出现BTX错误,于是随便找了台酷睿2的机器把mini系统装在ad0上,分区如下:
 
这个机器用光盘启动会出现BTX错误,于是随便找了台酷睿2的机器把mini系统装在ad0上,分区如下:
 +
 
/dev/ad0s1a on / (ufs, local, fsid 8ffe38491c7dd7c4)
 
/dev/ad0s1a on / (ufs, local, fsid 8ffe38491c7dd7c4)
 +
 
注意,没有分配任何SWAP,现在内存便宜,随时加!
 
注意,没有分配任何SWAP,现在内存便宜,随时加!
  
 
最小化安装系统:
 
最小化安装系统:
  
router# df
+
router# df
Filesystem  1K-blocks    Used      Avail Capacity  Mounted on
+
Filesystem  1K-blocks    Used      Avail Capacity  Mounted on
data/root  1427457408  18816 1427438592    0%    /
+
data/root  1427457408  18816 1427438592    0%    /
devfs                1      1          0  100%    /dev
+
devfs                1      1          0  100%    /dev
  
 
接下来做raidz:
 
接下来做raidz:
  
router# glabel label disk1 /dev/ad4
+
router# glabel label disk1 /dev/ad4
router# glabel label disk2 /dev/ad6
+
router# glabel label disk2 /dev/ad6
router# glabel label disk3 /dev/ad8
+
router# glabel label disk3 /dev/ad8
router# glabel label disk4 /dev/ad10
+
router# glabel label disk4 /dev/ad10
  
 
glabel给硬盘打上标签以后有个好处,即后续的磁盘存取使用逻辑名称,跟物理连接无关。
 
glabel给硬盘打上标签以后有个好处,即后续的磁盘存取使用逻辑名称,跟物理连接无关。
  
router# kldload zfs
+
router# kldload zfs
router# zpool create data raidz /dev/label/disk[1-4]
+
router# zpool create data raidz /dev/label/disk[1-4]
router# zpool status
+
router# zpool status
 
   pool: data
 
   pool: data
state: ONLINE
+
state: ONLINE
scrub: none requested
+
scrub: none requested
config:
+
config:
  
 
NAME            STATE    READ WRITE CKSUM
 
NAME            STATE    READ WRITE CKSUM
data            ONLINE      0    0    0
+
data            ONLINE      0    0    0
raidz1        ONLINE      0    0    0
+
raidz1        ONLINE      0    0    0
 
   label/disk1  ONLINE      0    0    0
 
   label/disk1  ONLINE      0    0    0
 
   label/disk2  ONLINE      0    0    0
 
   label/disk2  ONLINE      0    0    0
第66行: 第70行:
 
   label/disk4  ONLINE      0    0    0
 
   label/disk4  ONLINE      0    0    0
  
errors: No known data errors
+
errors: No known data errors
router# df -h
+
router# df -h
Filesystem    Size    Used  Avail Capacity  Mounted on
+
Filesystem    Size    Used  Avail Capacity  Mounted on
/dev/ad0s1a    484M    328M    117M    74%    /
+
/dev/ad0s1a    484M    328M    117M    74%    /
devfs          1.0K    1.0K      0B  100%    /dev
+
devfs          1.0K    1.0K      0B  100%    /dev
data          1.3T      0B    1.3T    0%    /data
+
data          1.3T      0B    1.3T    0%    /data
  
 
准备好了存储就可以把大部份系统移植到zfs里面去,留个/boot放在ufs上启动(FreeBSD Bootloader不能访问zfs),zfs的COW抗断电非常不错,ufs上面的内核只读启动,也很安全:
 
准备好了存储就可以把大部份系统移植到zfs里面去,留个/boot放在ufs上启动(FreeBSD Bootloader不能访问zfs),zfs的COW抗断电非常不错,ufs上面的内核只读启动,也很安全:
  
router# zfs set mountpoint=none data
+
router# zfs set mountpoint=none data
router# zfs create data/root
+
router# zfs create data/root
router# zfs create data/usr
+
router# zfs create data/usr
router# zfs create data/var
+
router# zfs create data/var
router# zfs create data/tmp
+
router# zfs create data/tmp
router# zfs set mountpoint=/data data/root
+
router# zfs set mountpoint=/data data/root
router# zfs set mountpoint=/data/usr data/usr
+
router# zfs set mountpoint=/data/usr data/usr
router# zfs set mountpoint=/data/var data/var
+
router# zfs set mountpoint=/data/var data/var
router# zfs set mountpoint=/data/tmp data/tmp
+
router# zfs set mountpoint=/data/tmp data/tmp
router# echo 'zfs_enable="YES"' >> /etc/rc.conf
+
router# echo 'zfs_enable="YES"' >> /etc/rc.conf
router# find -x / | cpio -pmd /data
+
router# find -x / | cpio -pmd /data
router# rm -rf /data/boot
+
router# rm -rf /data/boot
router# mkdir /data/bootdir
+
router# mkdir /data/bootdir
router# cd /data
+
router# cd /data
router# ln -s bootdir/boot boot
+
router# ln -s bootdir/boot boot
router# echo 'zfs_load="YES"' >> /boot/loader.conf
+
router# echo 'zfs_load="YES"' >> /boot/loader.conf
router# echo 'vfs.root.mountfrom="zfs:data/root"' >> /boot/loader.conf
+
router# echo 'vfs.root.mountfrom="zfs:data/root"' >> /boot/loader.conf
  
 
改一下/data/etc/fstab,改到新的boot上:
 
改一下/data/etc/fstab,改到新的boot上:
/dev/ad0s1a            /bootdir        ufs    rw              1      1
+
/dev/ad0s1a            /bootdir        ufs    rw              1      1
router# zfs set mountpoint=/tmp data/tmp
+
router# zfs set mountpoint=/tmp data/tmp
router# zfs set mountpoint=/usr data/usr
+
router# zfs set mountpoint=/usr data/usr
router# zfs set mountpoint=/var data/var
+
router# zfs set mountpoint=/var data/var
router# cd /
+
router# cd /
router# zfs set mountpoint=legacy data/root
+
router# zfs set mountpoint=legacy data/root
  
 
好了,基本系统就完成了,看看现在的存储结构:
 
好了,基本系统就完成了,看看现在的存储结构:
router# df -h
+
router# df -h
Filesystem    Size    Used  Avail Capacity  Mounted on
+
Filesystem    Size    Used  Avail Capacity  Mounted on
data/root      1.3T    18M    1.3T    0%    /
+
data/root      1.3T    18M    1.3T    0%    /
devfs          1.0K    1.0K      0B  100%    /dev
+
devfs          1.0K    1.0K      0B  100%    /dev
/dev/ad0s1a    484M    328M    117M    74%    /bootdir
+
/dev/ad0s1a    484M    328M    117M    74%    /bootdir
data/tmp      1.3T      0B    1.3T    0%    /tmp
+
data/tmp      1.3T      0B    1.3T    0%    /tmp
data/usr      1.3T    136M    1.3T    0%    /usr
+
data/usr      1.3T    136M    1.3T    0%    /usr
data/var      1.3T    256K    1.3T    0%    /var
+
data/var      1.3T    256K    1.3T    0%    /var
router# zfs list
+
router# zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
+
NAME        USED  AVAIL  REFER  MOUNTPOINT
data        155M  1.33T  26.9K  none
+
data        155M  1.33T  26.9K  none
data/root  18.4M  1.33T  18.4M  legacy
+
data/root  18.4M  1.33T  18.4M  legacy
data/tmp  32.9K  1.33T  32.9K  /tmp
+
data/tmp  32.9K  1.33T  32.9K  /tmp
data/usr    136M  1.33T  136M  /usr
+
data/usr    136M  1.33T  136M  /usr
data/var    316K  1.33T  316K  /var
+
data/var    316K  1.33T  316K  /var
  
 
zfs在FreeBSD7.0上还是需要微调,缺省的参数会在密集IO操作时导致内核崩溃(做NFS测试的时候很容易就碰上了)!
 
zfs在FreeBSD7.0上还是需要微调,缺省的参数会在密集IO操作时导致内核崩溃(做NFS测试的时候很容易就碰上了)!
router# echo 'vm.kmem_size_max="1073741824"' >> /boot/loader.conf
+
router# echo 'vm.kmem_size_max="1073741824"' >> /boot/loader.conf
router# echo 'vm.kmem_size="1073741824"' >> /boot/loader.conf
+
router# echo 'vm.kmem_size="1073741824"' >> /boot/loader.conf
  
 
下面这些东东扔进/etc/rc.conf:
 
下面这些东东扔进/etc/rc.conf:
  
dumpdev="NO" //不用SWAP设备
+
dumpdev="NO" //不用SWAP设备
fsck_y_enable="YES"
+
fsck_y_enable="YES"
sendmail_enable="NO"
+
sendmail_enable="NO"
sendmail_submit_enable="NO"
+
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
+
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
+
sendmail_msp_queue_enable="NO"
update_motd="NO"
+
update_motd="NO"
ntpdate_enable="YES"
+
ntpdate_enable="YES"
ntpd_enable="YES"
+
ntpd_enable="YES"
  
 
重启系统,一切OK!
 
重启系统,一切OK!
  
 
系统及内核更新:
 
系统及内核更新:
 +
 
=============
 
=============
 +
 
重建世界*_*:
 
重建世界*_*:
  
router# vi /usr/share/examples/cvsup/stable-supfile
+
router# vi /usr/share/examples/cvsup/stable-supfile
*default host=cvsup.jp.FreeBSD.org //选个快点的镜像就行了,其他不用动
+
*default host=cvsup.jp.FreeBSD.org //选个快点的镜像就行了,其他不用动
router# cd /usr/share/examples/cvsup
+
router# cd /usr/share/examples/cvsup
router# csup -g -L 2 stable-supfile //csup已经内置在base系统里了,不再需要cvsup
+
router# csup -g -L 2 stable-supfile //csup已经内置在base系统里了,不再需要cvsup
router# cd /usr/src
+
router# cd /usr/src
router# make buildworld
+
router# make buildworld
router# cd /usr/src/sys/amd64/conf
+
router# cd /usr/src/sys/amd64/conf
router# cp GENERIC GENERIC.orig
+
router# cp GENERIC GENERIC.orig
router# vi GENERIC
+
router# vi GENERIC
router# diff GENERIC GENERIC.orig
+
router# diff GENERIC GENERIC.orig
27c27
+
27c27
< #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+
< #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
---
+
---
> makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+
> makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
32c32
+
32c32
< #options INET6 # IPv6 communications protocols
+
< #options INET6 # IPv6 communications protocols
---
+
---
> options INET6 # IPv6 communications protocols
+
> options INET6 # IPv6 communications protocols
310,330d309
+
310,330d309
<
+
<
< # PF support
+
< # PF support
< device          pf
+
< device          pf
< device          pflog
+
< device          pflog
< device          pfsync
+
< device          pfsync
< options        ALTQ
+
< options        ALTQ
< options        ALTQ_CBQ        # Class Bases Queuing (CBQ)
+
< options        ALTQ_CBQ        # Class Bases Queuing (CBQ)
< options        ALTQ_RED        # Random Early Detection (RED)
+
< options        ALTQ_RED        # Random Early Detection (RED)
< options        ALTQ_RIO        # RED In/Out
+
< options        ALTQ_RIO        # RED In/Out
< options        ALTQ_HFSC      # Hierarchical Packet Scheduler (HFSC)
+
< options        ALTQ_HFSC      # Hierarchical Packet Scheduler (HFSC)
< options        ALTQ_PRIQ      # Priority Queuing (PRIQ)
+
< options        ALTQ_PRIQ      # Priority Queuing (PRIQ)
< options        ALTQ_NOPCC      # Required for SMP build
+
< options        ALTQ_NOPCC      # Required for SMP build
<
+
<
< # vlan support
+
< # vlan support
< device          vlan            #VLAN support (needs miibus)
+
< device          vlan            #VLAN support (needs miibus)
<
+
<
< # Network Performance
+
< # Network Performance
< options        PANIC_REBOOT_WAIT_TIME=0
+
< options        PANIC_REBOOT_WAIT_TIME=0
< options        DEVICE_POLLING
+
< options        DEVICE_POLLING
< options        HZ=2000
+
< options        HZ=2000
< options        IPSTEALTH
+
< options        IPSTEALTH
  
 
网卡全是Intel的,支持polling,ALTQ给VLAN用户做QoS,另外就是关掉了IPv6。别忘了把定制的GENERIC做个备份,省得下次同步源码的时候给覆盖了。
 
网卡全是Intel的,支持polling,ALTQ给VLAN用户做QoS,另外就是关掉了IPv6。别忘了把定制的GENERIC做个备份,省得下次同步源码的时候给覆盖了。
  
router# cp GENERIC GENERIC.20081210
+
router# cp GENERIC GENERIC.20081210
router# cd /usr/src
+
router# cd /usr/src
router# make buildkernel
+
router# make buildkernel
router# make installkernel
+
router# make installkernel
router# shutdown -r now
+
router# shutdown -r now
router# mergemaster -p
+
router# mergemaster -p
router# cd /usr/src
+
router# cd /usr/src
router# make installworld
+
router# make installworld
router# mergemaster
+
router# mergemaster
router# reboot
+
router# reboot
  
 
世界改造完成!
 
世界改造完成!
第198行: 第204行:
 
到这里就可以把/boot设成只读了:
 
到这里就可以把/boot设成只读了:
  
router# cat /etc/fstab
+
router# cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
+
# Device Mountpoint FStype Options Dump Pass#
/dev/ad0s1a /bootdir ufs ro 1 1
+
/dev/ad0s1a /bootdir ufs ro 1 1
router# mount
+
router# mount
data/root on / (zfs, local)
+
data/root on / (zfs, local)
devfs on /dev (devfs, local)
+
devfs on /dev (devfs, local)
/dev/ad0s1a on /bootdir (ufs, local, read-only)
+
/dev/ad0s1a on /bootdir (ufs, local, read-only)
data/opt on /opt (zfs, local)
+
data/opt on /opt (zfs, local)
data/tmp on /tmp (zfs, local)
+
data/tmp on /tmp (zfs, local)
data/usr on /usr (zfs, local)
+
data/usr on /usr (zfs, local)
data/var on /var (zfs, local)
+
data/var on /var (zfs, local)
  
 
安装应用软件:
 
安装应用软件:
 +
 
===========
 
===========
router# cd /usr/share/examples/cvsup
+
router# cd /usr/share/examples/cvsup
router# vi ports-supfile
+
router# vi ports-supfile
*default host=cvsup.jp.FreeBSD.org //选个快点的镜像
+
*default host=cvsup.jp.FreeBSD.org //选个快点的镜像
router# csup -g -L 2 ports-supfile
+
router# csup -g -L 2 ports-supfile
router# make index
+
router# make index
  
 
在编译所有软件以前,先编辑一下 /etc/make.conf,我的很简单:
 
在编译所有软件以前,先编辑一下 /etc/make.conf,我的很简单:
BATCH=yes
+
BATCH=yes
  
MASTER_SITE_BACKUP?= \
+
MASTER_SITE_BACKUP?= \
ftp://ftp.jp.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR}/\
+
ftp://ftp.jp.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR}/\
  
MASTER_SITE_OVERRIDE?= ${MASTER_SITE_BACKUP}
+
MASTER_SITE_OVERRIDE?= ${MASTER_SITE_BACKUP}
  
 
后面会个别使用make config,否则的话全部安静安装。
 
后面会个别使用make config,否则的话全部安静安装。
第232行: 第239行:
 
1、 postgresql
 
1、 postgresql
  
router# cd /usr/ports/databases/postgresql83-server
+
router# cd /usr/ports/databases/postgresql83-server
router# make install clean
+
router# make install clean
  
 
有几个地方需要注意:
 
有几个地方需要注意:
  
/usr/local/etc/periodic/daily/502.pgsql 做vacuum和backup的模板
+
/usr/local/etc/periodic/daily/502.pgsql 做vacuum和backup的模板
  
 
   options        SYSVSHM
 
   options        SYSVSHM
第254行: 第261行:
 
初始化数据库:
 
初始化数据库:
  
router# echo 'postgresql_enable="YES"' >> /etc/rc.conf
+
router# echo 'postgresql_enable="YES"' >> /etc/rc.conf
router# /usr/local/etc/rc.d/postgresql initdb
+
router# /usr/local/etc/rc.d/postgresql initdb
router# /usr/local/etc/rc.d/postgresql start
+
router# /usr/local/etc/rc.d/postgresql start
router# su - pgsql -c 'createuser sysadm' //pgsql是postgresql的UNIX系统帐户,sysadm是postgresql内部的数据库帐户
+
router# su - pgsql -c 'createuser sysadm' //pgsql是postgresql的UNIX系统帐户,sysadm是postgresql内部的数据库帐户
router# su - pgsql -c 'createdb -O sysadm kydb' //给sysadm建个库叫kydb
+
router# su - pgsql -c 'createdb -O sysadm kydb' //给sysadm建个库叫kydb
router# psql kydb sysadm //以后就这样在命令行登录我们的库进行管理
+
router# psql kydb sysadm //以后就这样在命令行登录我们的库进行管理
  
 
当然别忘了修改我们的数据库登录密码:
 
当然别忘了修改我们的数据库登录密码:
第266行: 第273行:
  
 
改完密码以调整一下pg_hba.conf,然后重启一下:
 
改完密码以调整一下pg_hba.conf,然后重启一下:
 +
 
pg_hba.conf文件里面屏蔽ipv6,然后unix socket和ipv4的连接开启md5。
 
pg_hba.conf文件里面屏蔽ipv6,然后unix socket和ipv4的连接开启md5。
  
# "local" is for Unix domain socket connections only
+
# "local" is for Unix domain socket connections only
local  all        all                              md5
+
local  all        all                              md5
# IPv4 local connections:
+
# IPv4 local connections:
host    all        all        127.0.0.1/32          md5
+
host    all        all        127.0.0.1/32          md5
# IPv6 local connections:
+
# IPv6 local connections:
host    all        all        ::1/128              reject
+
host    all        all        ::1/128              reject
router# /usr/local/etc/rc.d/postgresql restart
+
router# /usr/local/etc/rc.d/postgresql restart
  
 
2、freeradius
 
2、freeradius
router# cd /usr/ports/net/freeradius2
+
router# cd /usr/ports/net/freeradius2
router# make config
+
router# make config
[X] USER          Run as user freeradius, group freeradius
+
[X] USER          Run as user freeradius, group freeradius
[X] PGSQL        With PostgreSQL database support
+
[X] PGSQL        With PostgreSQL database support
router# make install clean
+
router# make install clean
  
 
配置FreeRadius:
 
配置FreeRadius:
第一步,/usr/local/etc/raddb/clients.conf,认证客户端配置,这一步建立一个客户端连接,所有需要使用AAA服务的软件通过这个客户端获取AAA认证信息:
 
  
client localhost {
+
第一步,/usr/local/etc/raddb/clients.conf,认证客户端配置,这一步建立一个客户端连接,所有需要使用AAA服务的软件通过这个客户端获取AAA
ipaddr = 127.0.0.1
+
认证信息:
secret = testing123
+
 
require_message_authenticator = no
+
client localhost {
nastype = other
+
ipaddr = 127.0.0.1
}
+
secret = testing123
 +
require_message_authenticator = no
 +
nastype = other
 +
}
  
 
第二步,/usr/local/etc/raddb/dictionary,PPPoE服务我用的是mpd,需要加上mpd的字典:
 
第二步,/usr/local/etc/raddb/dictionary,PPPoE服务我用的是mpd,需要加上mpd的字典:
  
$INCLUDE /usr/local/share/freeradius/dictionary
+
$INCLUDE /usr/local/share/freeradius/dictionary
$INCLUDE /usr/local/share/freeradius/dictionary.mpd
+
$INCLUDE /usr/local/share/freeradius/dictionary.mpd
  
 
dictionary.mpd 在mpd的源码包里面,可以先把mpd解开拿过来用:
 
dictionary.mpd 在mpd的源码包里面,可以先把mpd解开拿过来用:
  
router# cd /usr/ports/net/mpd5
+
router# cd /usr/ports/net/mpd5
router# make extract
+
router# make extract
router# cp work/mpd-5.2/conf/dictionary.mpd /usr/local/share/freeradius/
+
router# cp work/mpd-5.2/conf/dictionary.mpd /usr/local/share/freeradius/
  
 
第三步,/usr/local/etc/raddb/radiusd.conf,这个是主要进程配置,但是很多细节配置,例如数据库连接配置等都独立到各自文件了,所以这里很简单,基本上没有任何改动:
 
第三步,/usr/local/etc/raddb/radiusd.conf,这个是主要进程配置,但是很多细节配置,例如数据库连接配置等都独立到各自文件了,所以这里很简单,基本上没有任何改动:
  
prefix = /usr/local
+
prefix = /usr/local
exec_prefix = ${prefix}
+
exec_prefix = ${prefix}
sysconfdir = ${prefix}/etc
+
sysconfdir = ${prefix}/etc
localstatedir = /var
+
localstatedir = /var
sbindir = ${exec_prefix}/sbin
+
sbindir = ${exec_prefix}/sbin
logdir = /var/log
+
logdir = /var/log
raddbdir = ${sysconfdir}/raddb
+
raddbdir = ${sysconfdir}/raddb
radacctdir = ${logdir}/radacct
+
radacctdir = ${logdir}/radacct
confdir = ${raddbdir}
+
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/radiusd
+
run_dir = ${localstatedir}/run/radiusd
db_dir = $(raddbdir)
+
db_dir = $(raddbdir)
libdir = /usr/local/lib/freeradius-2.0.5
+
libdir = /usr/local/lib/freeradius-2.0.5
pidfile = ${run_dir}/radiusd.pid
+
pidfile = ${run_dir}/radiusd.pid
user = freeradius
+
user = freeradius
group = freeradius
+
group = freeradius
max_request_time = 30
+
max_request_time = 30
cleanup_delay = 5
+
cleanup_delay = 5
max_requests = 1024
+
max_requests = 1024
listen {
+
listen {
type = auth
+
type = auth
ipaddr = 127.0.0.1
+
ipaddr = 127.0.0.1
port = 0
+
port = 0
}
+
}
listen {
+
listen {
type = acct
+
type = acct
ipaddr = 127.0.0.1
+
ipaddr = 127.0.0.1
port = 0
+
port = 0
}
+
}
hostname_lookups = no
+
hostname_lookups = no
allow_core_dumps = no
+
allow_core_dumps = no
regular_expressions = yes
+
regular_expressions = yes
extended_expressions = yes
+
extended_expressions = yes
log {
+
log {
destination = files
+
destination = files
file = ${logdir}/radius.log
+
file = ${logdir}/radius.log
syslog_facility = daemon
+
syslog_facility = daemon
stripped_names = no
+
stripped_names = no
auth = no
+
auth = no
auth_badpass = no
+
auth_badpass = no
auth_goodpass = no
+
auth_goodpass = no
}
+
}
checkrad = ${sbindir}/checkrad
+
checkrad = ${sbindir}/checkrad
security {
+
security {
max_attributes = 200
+
max_attributes = 200
reject_delay = 1
+
reject_delay = 1
status_server = yes
+
status_server = yes
}
+
}
proxy_requests  = yes
+
proxy_requests  = yes
$INCLUDE proxy.conf
+
$INCLUDE proxy.conf
$INCLUDE clients.conf
+
$INCLUDE clients.conf
snmp = no
+
snmp = no
$INCLUDE snmp.conf
+
$INCLUDE snmp.conf
thread pool {
+
thread pool {
start_servers = 5
+
start_servers = 5
max_servers = 32
+
max_servers = 32
min_spare_servers = 3
+
min_spare_servers = 3
max_spare_servers = 10
+
max_spare_servers = 10
max_requests_per_server = 0
+
max_requests_per_server = 0
}
+
}
modules {
+
modules {
$INCLUDE ${confdir}/modules/
+
$INCLUDE ${confdir}/modules/
$INCLUDE eap.conf
+
$INCLUDE eap.conf
$INCLUDE sql.conf
+
$INCLUDE sql.conf
$INCLUDE sql/postgresql/counter.conf
+
$INCLUDE sql/postgresql/counter.conf
}
+
}
instantiate {
+
instantiate {
exec
+
exec
expr
+
expr
expiration
+
expiration
logintime
+
logintime
}
+
}
$INCLUDE policy.conf
+
$INCLUDE policy.conf
$INCLUDE sites-enabled/
+
$INCLUDE sites-enabled/
  
 
第四步,/usr/local/etc/raddb/sql.conf,数据库连接配置和AAA访问的表定义:
 
第四步,/usr/local/etc/raddb/sql.conf,数据库连接配置和AAA访问的表定义:
  
sql {
+
sql {
database = "postgresql"
+
database = "postgresql"
driver = "rlm_sql_${database}"
+
driver = "rlm_sql_${database}"
server = "localhost"
+
server = "localhost"
login = "sysadm"
+
login = "sysadm"
password = "123456"
+
password = "123456"
radius_db = "kydb"
+
radius_db = "kydb"
acct_table1 = "radacct"
+
acct_table1 = "radacct"
acct_table2 = "radacct"
+
acct_table2 = "radacct"
postauth_table = "radpostauth"
+
postauth_table = "radpostauth"
authcheck_table = "radcheck"
+
authcheck_table = "radcheck"
authreply_table = "radreply"
+
authreply_table = "radreply"
groupcheck_table = "radgroupcheck"
+
groupcheck_table = "radgroupcheck"
groupreply_table = "radgroupreply"
+
groupreply_table = "radgroupreply"
usergroup_table = "radusergroup"
+
usergroup_table = "radusergroup"
deletestalesessions = yes
+
deletestalesessions = yes
sqltrace = no
+
sqltrace = no
sqltracefile = ${logdir}/sqltrace.sql
+
sqltracefile = ${logdir}/sqltrace.sql
num_sql_socks = 5
+
num_sql_socks = 5
connect_failure_retry_delay = 60
+
connect_failure_retry_delay = 60
nas_table = "nas"
+
nas_table = "nas"
$INCLUDE sql/${database}/dialup.conf
+
$INCLUDE sql/${database}/dialup.conf
}
+
}
  
 
第五步,主服务配置文件/usr/local/etc/raddb/sites-available/default
 
第五步,主服务配置文件/usr/local/etc/raddb/sites-available/default
  
authorize {
+
authorize {
preprocess
+
preprocess
chap
+
chap
mschap
+
mschap
suffix
+
suffix
sql
+
sql
pap
+
pap
}
+
}
authenticate {
+
authenticate {
Auth-Type PAP {
+
Auth-Type PAP {
pap
+
pap
}
+
}
Auth-Type CHAP {
+
Auth-Type CHAP {
chap
+
chap
}
+
}
Auth-Type MS-CHAP {
+
Auth-Type MS-CHAP {
mschap
+
mschap
}
+
}
}
+
}
preacct {
+
preacct {
preprocess
+
preprocess
acct_unique
+
acct_unique
}
+
}
accounting {
+
accounting {
sql
+
sql
}
+
}
session {
+
session {
sql
+
sql
}
+
}
post-auth {
+
post-auth {
sql
+
sql
Post-Auth-Type REJECT {
+
Post-Auth-Type REJECT {
attr_filter.access_reject
+
attr_filter.access_reject
}
+
}
}
+
}
pre-proxy {
+
pre-proxy {
}
+
}
post-proxy {
+
post-proxy {
}
+
}
  
 
AAA 服务配置就OK了,freeradius网站有很不错的书可以参考。另外说一下,实际环境中我把所有的日志输出到/dev/console了。
 
AAA 服务配置就OK了,freeradius网站有很不错的书可以参考。另外说一下,实际环境中我把所有的日志输出到/dev/console了。
第452行: 第462行:
 
第六步,部署AAA表:
 
第六步,部署AAA表:
  
router# cd /usr/local/etc/raddb/sql/postgresql
+
router# cd /usr/local/etc/raddb/sql/postgresql
router# psql -U sysadm kydb < schema.sql
+
router# psql -U sysadm kydb < schema.sql
  
 
看一下都部署了哪些表:
 
看一下都部署了哪些表:
  
kydb=> \dt
+
kydb=> \dt
            List of relations
+
            List of relations
Schema |    Name      | Type  | Owner   
+
Schema |    Name      | Type  | Owner   
--------+---------------+-------+--------
+
--------+---------------+-------+--------
public | radacct      | table | sysadm
+
public | radacct      | table | sysadm
public | radcheck      | table | sysadm
+
public | radcheck      | table | sysadm  
public | radgroupcheck | table | sysadm
+
public | radgroupcheck | table | sysadm
public | radgroupreply | table | sysadm
+
public | radgroupreply | table | sysadm
public | radpostauth  | table | sysadm
+
public | radpostauth  | table | sysadm
public | radreply      | table | sysadm
+
public | radreply      | table | sysadm
public | radusergroup  | table | sysadm
+
public | radusergroup  | table | sysadm
(7 rows)
+
(7 rows)
  
 
OK!可以放认证数据了,我这里大多数用户接入使用PPPoE拨号方式,配合mpd的流量管理功能(ng_car),类似电信的ADSL拨号帐户,只是我们的传输不是ADSL而是标准以太网,在认证上跟ADSL没有什么分别,不过由于市面上各种各样的所谓“宽带路由器”chap握手兼容性太差,所以我这里使用pap,建立一个拨号帐号基本上分为组、用户和返回信息等配置。
 
OK!可以放认证数据了,我这里大多数用户接入使用PPPoE拨号方式,配合mpd的流量管理功能(ng_car),类似电信的ADSL拨号帐户,只是我们的传输不是ADSL而是标准以太网,在认证上跟ADSL没有什么分别,不过由于市面上各种各样的所谓“宽带路由器”chap握手兼容性太差,所以我这里使用pap,建立一个拨号帐号基本上分为组、用户和返回信息等配置。
 
先说说这些表的用途:
 
先说说这些表的用途:
radacct:这个是帐务表,就是用户使用情况的记录,比较关心的是输入输出的字节数,后面给用户出mrtg图的地方会用
+
radacct:这个是帐务表,就是用户使用情况的记录,比较关心的是输入输出的字节数,后面给用户出mrtg图的地方会用
radcheck:用户的帐号密码表
+
radcheck:用户的帐号密码表
radgroupcheck:组的认证信息表,没有用到
+
radgroupcheck:组的认证信息表,没有用到
radgroupreply:组的返回信息,所有用户通用的配置可以扔在这里
+
radgroupreply:组的返回信息,所有用户通用的配置可以扔在这里
radpostauth:记录认证行为的日志表
+
radpostauth:记录认证行为的日志表
radreply:针对每用户的返回信息,带宽数据就在这里设定
+
radreply:针对每用户的返回信息,带宽数据就在这里设定
radusergroup:用户和组的对应关系表
+
radusergroup:用户和组的对应关系表
 
我们的应用要求比较简单,所有用户都在一个组,每个用户拥有自己的带宽,因此我们的任务就是定制帐号密码和带宽而已。
 
我们的应用要求比较简单,所有用户都在一个组,每个用户拥有自己的带宽,因此我们的任务就是定制帐号密码和带宽而已。
 
首先建立组的返回信息:
 
首先建立组的返回信息:
  
kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Framed-Protocol', ':=', 'PPP');
+
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
 
INSERT 0 1
kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Framed-Compression', ':=', 'Van-Jacobsen-TCP-IP');
+
kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Service-Type', ':=', 'Framed-User');
 
INSERT 0 1
 
INSERT 0 1
 +
kydb=> INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES ('PPPoE', 'Framed-Compression', ':=', 'Van-Jacobsen-TCP-IP');
 +
INSERT 0 1
  
 
别问我那些attributes是什么意思,这个还是自己老老实实看mpd的手册。
 
别问我那些attributes是什么意思,这个还是自己老老实实看mpd的手册。
 
开个用户 “test”,分配给他上行128KBps和下行256KBps的带宽,这样就可以了:
 
开个用户 “test”,分配给他上行128KBps和下行256KBps的带宽,这样就可以了:
  
kydb=> INSERT INTO radusergroup (username, groupname) VALUES ('test', 'PPPoE');
+
kydb=> INSERT INTO radusergroup (username, groupname) VALUES ('test', 'PPPoE');
 
INSERT 0 1 //先把test加入PPPoE组
 
INSERT 0 1 //先把test加入PPPoE组
kydb=> INSERT INTO radcheck (username, attribute, op, value) VALUES ('test', 'Cleartext-Password', ':=', 'test123');
+
kydb=> INSERT INTO radcheck (username, attribute, op, value) VALUES ('test', 'Cleartext-Password', ':=', 'test123');
 
INSERT 0 1 //建立test的认证帐号和密码
 
INSERT 0 1 //建立test的认证帐号和密码
kydb=> INSERT INTO radreply (username, attribute, op, value) VALUES ('test', 'mpd-limit', '+=', 'in#1=all rate-limit 128000 150000 300000');
+
kydb=> INSERT INTO radreply (username, attribute, op, value) VALUES ('test', 'mpd-limit', '+=', 'in#1=all rate-limit 128000 150000 300000');
INSERT 0 1 //上行带宽
+
INSERT 0 1 //上行带宽
kydb=> INSERT INTO radreply (username, attribute, op, value) VALUES ('test', 'mpd-limit', '+=', 'out#1=all rate-limit 256000 150000 300000');
+
kydb=> INSERT INTO radreply (username, attribute, op, value) VALUES ('test', 'mpd-limit', '+=', 'out#1=all rate-limit 256000 150000 300000');
INSERT 0 1 //下行带宽
+
INSERT 0 1 //下行带宽
  
 
然后启动AAA:
 
然后启动AAA:
  
router# radiusd -X //这样会进入调试模式,所有模块加载的过程都能看见,认证的过程也能看见,找问题比较方便。
+
router# radiusd -X //这样会进入调试模式,所有模块加载的过程都能看见,认证的过程也能看见,找问题比较方便。
router# radtest test test123 localhost 10 testing123
+
router# radtest test test123 localhost 10 testing123
Sending Access-Request of id 156 to 127.0.0.1 port 1812
+
Sending Access-Request of id 156 to 127.0.0.1 port 1812
User-Name = "test"
+
User-Name = "test"
User-Password = "test123"
+
User-Password = "test123"
NAS-IP-Address = 172.18.30.10
+
NAS-IP-Address = 172.18.30.10
NAS-Port = 10
+
NAS-Port = 10
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=156, length=135
+
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 = "in#1=all rate-limit 128000 150000 300000"
mpd-limit = "out#1=all rate-limit 256000 150000 300000"
+
mpd-limit = "out#1=all rate-limit 256000 150000 300000"
Framed-Protocol = PPP
+
Framed-Protocol = PPP
Service-Type = Framed-User
+
Service-Type = Framed-User
Framed-Compression = Van-Jacobson-TCP-IP
+
Framed-Compression = Van-Jacobson-TCP-IP
  
 
rad_recv就是认证成功以后得到的返回信息。
 
rad_recv就是认证成功以后得到的返回信息。
 
如果出错,比如我们密码错了:
 
如果出错,比如我们密码错了:
  
router# radtest test 123 localhost 10 testing123
+
router# radtest test 123 localhost 10 testing123
Sending Access-Request of id 167 to 127.0.0.1 port 1812
+
Sending Access-Request of id 167 to 127.0.0.1 port 1812
User-Name = "test"
+
User-Name = "test"
User-Password = "123"
+
User-Password = "123"
NAS-IP-Address = 172.18.30.10
+
NAS-IP-Address = 172.18.30.10
NAS-Port = 10
+
NAS-Port = 10
rad_recv: Access-Reject packet from host 127.0.0.1 port 1812, id=167, length=20
+
rad_recv: Access-Reject packet from host 127.0.0.1 port 1812, id=167, length=20
  
 
我们被reject了,AAA控制台上这样显示:
 
我们被reject了,AAA控制台上这样显示:
  
auth: type "PAP"
+
auth: type "PAP"
+- entering group PAP
+
+- entering group PAP
rlm_pap: login attempt with password "123"
+
rlm_pap: login attempt with password "123"
rlm_pap: Using clear text password "test123"
+
rlm_pap: Using clear text password "test123"
rlm_pap: Passwords don't match
+
rlm_pap: Passwords don't match
++[pap] returns reject
+
++[pap] returns reject
  
 
好了,AAA安装配置到此结束,可以正式启用了:
 
好了,AAA安装配置到此结束,可以正式启用了:
  
router# echo 'radiusd_enable="YES"' >> /etc/rc.conf
+
router# echo 'radiusd_enable="YES"' >> /etc/rc.conf
router# touch /var/log/radius.log
+
router# touch /var/log/radius.log
router# chown freeradius:freeradius /var/log/radius.log
+
router# chown freeradius:freeradius /var/log/radius.log
router# /usr/local/etc/rc.d/radiusd start
+
router# /usr/local/etc/rc.d/radiusd start
router# sockstat -l
+
router# sockstat -l
USER    COMMAND    PID  FD PROTO  LOCAL ADDRESS        FOREIGN ADDRESS       
+
USER    COMMAND    PID  FD PROTO  LOCAL ADDRESS        FOREIGN ADDRESS       
freeradiusradiusd  3518  10 udp4  127.0.0.1:1812        *:*
+
freeradiusradiusd  3518  10 udp4  127.0.0.1:1812        *:*
freeradiusradiusd  3518  11 udp4  127.0.0.1:1813        *:*
+
freeradiusradiusd  3518  11 udp4  127.0.0.1:1813        *:*
freeradiusradiusd  3518  12 udp4  127.0.0.1:1814        *:*
+
freeradiusradiusd  3518  12 udp4  127.0.0.1:1814        *:*
pgsql    postgres  2425  4  tcp4  127.0.0.1:5432        *:*
+
pgsql    postgres  2425  4  tcp4  127.0.0.1:5432        *:*
pgsql    postgres  2425  5  stream /tmp/.s.PGSQL.5432
+
pgsql    postgres  2425  5  stream /tmp/.s.PGSQL.5432
root    sshd      1067  3  tcp4  *:6789                *:*
+
root    sshd      1067  3  tcp4  *:6789                *:*
root    ntpd      1009  20 udp4  *:123                *:*
+
root    ntpd      1009  20 udp4  *:123                *:*
root    ntpd      1009  21 udp4  172.18.30.210:123    *:*
+
root    ntpd      1009  21 udp4  172.18.30.210:123    *:*
root    ntpd      1009  22 udp4  192.168.1.1:123      *:*
+
root    ntpd      1009  22 udp4  192.168.1.1:123      *:*
root    ntpd      1009  23 udp4  127.0.0.1:123        *:*
+
root    ntpd      1009  23 udp4  127.0.0.1:123        *:*
root    syslogd    916  4  dgram  /var/run/log
+
root    syslogd    916  4  dgram  /var/run/log
root    syslogd    916  5  dgram  /var/run/logpriv
+
root    syslogd    916  5  dgram  /var/run/logpriv
root    syslogd    916  6  udp4  *:514                *:*
+
root    syslogd    916  6  udp4  *:514                *:*
root    devd      858  4  stream /var/run/devd.pipe
+
root    devd      858  4  stream /var/run/devd.pipe
  
 
3、 mpd
 
3、 mpd
第564行: 第574行:
 
mpd 启用流量计数需要安装ng_ipacct,安装比较麻烦,首先编译好的模块要写入/boot,因此要临时把/boot挂载成rw,另外需要内核源码,我们前面改造过世界:-),该有的都有了:
 
mpd 启用流量计数需要安装ng_ipacct,安装比较麻烦,首先编译好的模块要写入/boot,因此要临时把/boot挂载成rw,另外需要内核源码,我们前面改造过世界:-),该有的都有了:
  
router# cd /usr/ports/net-mgmt/ng_ipacct
+
router# cd /usr/ports/net-mgmt/ng_ipacct
router# make install clean
+
router# make install clean
  
 
这是/usr/local/etc /ng_ipacct.conf,我这里并没有修改缺省配置文件,mpd需要使用ng_ipacct模块,我们需要的是那个模块,不需要启动 ng_ipacct进程。
 
这是/usr/local/etc /ng_ipacct.conf,我这里并没有修改缺省配置文件,mpd需要使用ng_ipacct模块,我们需要的是那个模块,不需要启动 ng_ipacct进程。
  
ng_ipacct_modules_load="YES"
+
ng_ipacct_modules_load="YES"
ng_ipacct_modules_list="netgraph ng_ether ng_ipacct"
+
ng_ipacct_modules_list="netgraph ng_ether ng_ipacct"
ng_ipacct_default_ether_start='
+
ng_ipacct_default_ether_start='
mkpeer %%iface%%: tee lower right
+
mkpeer %%iface%%: tee lower right
name %%iface%%:lower %%iface%%_tee
+
name %%iface%%:lower %%iface%%_tee
connect %%iface%%: lower upper left
+
connect %%iface%%: lower upper left
mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
+
mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_ip_acct
+
name %%iface%%_tee:right2left %%iface%%_ip_acct
connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
+
connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'
+
'
ng_ipacct_default_ether_stop='
+
ng_ipacct_default_ether_stop='
shutdown %%iface%%_ip_acct:
+
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_tee:
+
shutdown %%iface%%_tee:
shutdown %%iface%%:
+
shutdown %%iface%%:
'
+
'
ng_ipacct_bpf_ether_start='
+
ng_ipacct_bpf_ether_start='
mkpeer %%iface%%: tee lower right
+
mkpeer %%iface%%: tee lower right
name %%iface%%:lower %%iface%%_tee
+
name %%iface%%:lower %%iface%%_tee
connect %%iface%%: lower upper left
+
connect %%iface%%: lower upper left
mkpeer %%iface%%_tee: bpf right2left %%iface%%_in
+
mkpeer %%iface%%_tee: bpf right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_bpf
+
name %%iface%%_tee:right2left %%iface%%_bpf
connect %%iface%%_tee: right2left left2right %%iface%%_out
+
connect %%iface%%_tee: right2left left2right %%iface%%_out
mkpeer %%iface%%_bpf: ipacct %%iface%%_match_in %%iface%%_in
+
mkpeer %%iface%%_bpf: ipacct %%iface%%_match_in %%iface%%_in
name %%iface%%_bpf:%%iface%%_match_in %%iface%%_ip_acct
+
name %%iface%%_bpf:%%iface%%_match_in %%iface%%_ip_acct
connect %%iface%%_bpf: %%iface%%_ip_acct: %%iface%%_match_out %%iface%%_out
+
connect %%iface%%_bpf: %%iface%%_ip_acct: %%iface%%_match_out %%iface%%_out
'
+
'
ng_ipacct_bpf_ether_stop='
+
ng_ipacct_bpf_ether_stop='
shutdown %%iface%%_ip_acct:
+
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_bpf:
+
shutdown %%iface%%_bpf:
shutdown %%iface%%_tee:
+
shutdown %%iface%%_tee:
shutdown %%iface%%:
+
shutdown %%iface%%:
'
+
'
 
ng_ipacct_xl0_start=${ng_ipacct_default_ether_start}
 
ng_ipacct_xl0_start=${ng_ipacct_default_ether_start}
 
ng_ipacct_xl0_stop=${ng_ipacct_default_ether_stop}
 
ng_ipacct_xl0_stop=${ng_ipacct_default_ether_stop}

2011年3月2日 (三) 05:03的版本

最近接到任务,要为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

  1. network interfaces

ext_if = "fxp1" int_if = "fxp0" lo_if = "lo0"

  1. tables

table <rfc1918> const { 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

  1. 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

  1. scrub

scrub in all

  1. 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 )

  1. 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 )

  1. nat for lan

nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if)

  1. 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>

  1. 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

  1. 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>

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

变换
操作
导航
工具箱