LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 5859|回复: 29

Linux网工学习笔记(更新iptables第一章) 已编辑

[复制链接]
发表于 2010-6-25 13:55:21 | 显示全部楼层 |阅读模式
长久以来一直都是咱这里提问,很少帮助别人。最近在看一个视频教程,索性写点儿笔记,发上来,可能帮到一些新鸟吧(虽然我挺菜)。希望大家支持!

如果值得转载,请务必注明出处。http://www.linuxsir.cn/bbs/showthread.php?p=2099509#post2099509

另外:学习环境用的CentOS5.5,极个别指令不通用,请触类旁通吧……


十六薙夜血的笔记(1)——配置网卡和DHCP服务器

[color="Red"]网络配置和DHCP

查看主机名:hostname
修改主机名:编辑/etc/sysconfig/network文件:HOSTNAME=xxxxx(需要重启),或者直接用hostname xxxxx。
让自己找到自己:修改/etc/hosts。

修改网络设置:system-config-network-x有三种方式可选。
网卡配置文件:/etc/sysconf/network-script/ifcfg-eth0
生效:service netowrk restart
立即生效方式:ifconfig eth0 ip //但是没有修改配置文件,重启后就消失

安装dhcp包。
查看软件包安装了什么:rpm –ql dhcp
其中的dhcpd.leases是保存租约的

复制样例文件到/etc下:cp /usr/share/doc/dhcp-3.0.5/dhcpd.conf.sample /etc/dhcpd.conf
查看这个conf怎么配:man dhcp.conf

配置DHCP服务器:
ddns-update-style interim;
ignore client-updates;

subnet 192.168.248.0 netmask 255.255.255.0 {

# --- default gateway
option routers 192.168.248.11;
option subnet-mask 255.255.255.0;

# option nis-domain "domain.org";
# option domain-name "domain.org";
# option domain-name-servers 192.168.1.1;

option time-offset -18000; # Eastern Standard Time
# option ntp-servers 192.168.1.1;
# option netbios-name-servers 192.168.1.1;
# --- Selects point-to-point node (default is hybrid). Don't change this unless
# -- you understand Netbios very well
# option netbios-node-type 2;

range dynamic-bootp 192.168.248.128 192.168.248.130;
default-lease-time 21600;
max-lease-time 43200;

# we want the nameserver to appear at a fixed address
host ns {
next-server marvin.redhat.com;
hardware ethernet 12:34:56:78:AB:CD;
fixed-address 207.175.42.254;
}
}

配置客户端:
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes

查看当前客户端:
more /var/lib/dhcpd/dhcpd.leases

为某个客户端指定IP:
# we want the nameserver to appear at a fixed address
host ns {
next-server marvin.redhat.com;
hardware ethernet 00:0C:29:82:F7:36; //修改为客户端的mac地址
fixed-address 192.168.248.129;
}

[color="red"]DHCP中继
实验拓扑如图所示:
[IMG]https://qkzabg.bay.livefilestore.com/y1mOqJEFTte3Owe6hm8H6HSOsZFIyFIOmMnqNGfW_Uz9PkB_LH0uzy7ZibXus8rs_EO0rvw2BCufg1q01d6tAE8TFm74-rtZDMAPYuwPmUrka04vO1tsE0kiRoe2J1ZCjc4sj-dbC7XbqktNTvAKfdNNA/DHCP%E4%B8%AD%E7%BB%A7%E6%8B%93%E6%89%91_thumb[4].jpg?download&psid=1[/IMG]

在原有DHCP服务器的基础上配制出DHCP中继,并且将客户端放在DHCP中继的网段内。两个网段的连接使用一台LINUX作为路由。

原有DHCP服务器地址为192.168.248.10,新的网段DHCP为192.168.249.10。

1、开启路由功能
在配置完路由服务器的两个网卡后,看是否开启了路由功能:cat /proc/sys/net/ipv4/ip_forward,看是否为1
如果不是就改成1:echo "1" > /proc/sys/net/ipv4/ip_forward  //会在服务重启实恢复到0。
路由开启。

2、配置中继服务器
配置文件是:/etc/sysconfig/dhcrelay  //通过 rpm –ql dhcp就找到了
修改这个文件:
# Command line options here
INTERFACES="eth0"  //是那个网卡干这活就写哪个
DHCPSERVERS="192.168.248.10"  //这是原始DHCP服务器的地址
起服务: service dhcrelay start

3、修改原服务器,增加新的网段
打开配置文件,复制subnet开始的配置部分并把ip修改为新的网段。  //nyy可以从光标处开始复制n行,p复制:
subnet 192.168.249.0 netmask 255.255.255.0 {

# --- default gateway
        option routers                  192.168.249.11;
        option subnet-mask              255.255.255.0;

#       option nis-domain               "domain.org";
#       option domain-name              "domain.org";
#       option domain-name-servers      192.168.1.1;

        option time-offset              -18000; # Eastern Standard Time
#       option ntp-servers              192.168.1.1;
#       option netbios-name-servers     192.168.1.1;
# --- Selects point-to-point node (default is hybrid). Don't change this unless
# -- you understand Netbios very well
#       option netbios-node-type 2;

        range dynamic-bootp 192.168.249.50 192.168.249.60;
        default-lease-time 21600;
        max-lease-time 43200;

        # we want the nameserver to appear at a fixed address
        host ns1 {  //主意主机名不能重复
                next-server marvin.redhat.com;
                hardware ethernet 00:0C:29:82:F7:36;
                fixed-address 192.168.249.55;
        }
}

重启服务。

客户机测试,可以获取新的地址。

注意:请关闭路由服务器的防火墙,为此折腾我半天……

------------------------------------------------------------------------------------------
[color="red"]NIS

安装:
检查是否安装了服务:rpm –qa | grep ypserv  \\其实就是yellow page
这个服务是非独立服务,由xinetd守护。
查询yp相关软件包:rpm –qa | grep yp
ypbind是客户端,yptool是相关工具。
安装服务:rpm -ivh ypserv*

修改主机名,加入NIS域:
hostname ypserver.thanatos.org
修改文件/etc/sysconfig/network:
hostname=ypserver.thanatos.org
NISDOMAIN=thanatos.org  \\加入NIS
nisdomainname指令反馈(none),表示没有加入域
nisdomainname thanatos.org  \\重启后会失效
修改/etc/rc.d/rc.local:/bin/nisdomainname thanatos.org  \\以后开机自动执行加入NIS域
重亲启动:reboot

修改配置文件:
vi /etc/ypserv.conf
其中给处理配置实例,如下:


# under MSDOG everbody is root and can access ports < 1024 !!!
*                          : *       : shadow.byname    : port
*                          : *       : passwd.adjunct.byname : port
注释掉以上两行后添加新的配置,把本机地址加入,并拒绝不想要的地址:


192.168.248.0/255.255.255.0     :*      :*      :none
127.0.0.0/255.255.255.0         :*      :*      :none
*                               :*      :*      :deny

进入/var/yp目录,创建securenets文件,添加以下内容:
host 127.0.0.1  \\允许的主机
255.255.255.0 192.168.248.0  \\允许的网段,掩码在前

重启服务:service ypserv start
chkconfig time on
chkconfig time-udp on
service xinetd restart
service portmap status  \\判断是否启动

实验:
增加账号:useradd testuser
passwd testuser
创建数据库:/usr/lib/yp/ypinit –m
执行后生成的文件在/var/yp下的域命名文件夹中。
服务器端配置完毕。

配置客户端:
检查是否安装了客户端软件:rpm –qa | grep yp
vi /etc/hosts
192.168.248.10 ypserver.thanatos.org
加入域:nisdomainname thanatos.org
修改配置文件:/etc/sysconfig/network
NISDOMAIN=thanatos.org  \\让系统重启也知道加入哪个域
vi /etc/rc.d/rc.local
/bin/nisdomain thanatos.org  \\以后开机就加入该域
vi /etc/yp.conf
加入:domain thanatos.org server ypserver.thanatos.org  \\让系统知道找谁加域
vi /etc/nsswitch.conf  \\让系统出了在本地文件找用户信息外还去NIS找
passwd: file nis
shadow: file nis
group: file nis
确保portmap启动:service portmap status
service ypbind start 后系统自动寻找服务器  \\在此之前请配置好防火墙放流量
ypwhich
ypcat –x
ypcat passwd

重新登录客户端,使用nis账户,成功。

------------------------------------------------------------------------------------------------------------------------------------
[color="Red"]samba

分两种情况考虑,一种是win共享,linux访问;一种是linux共享,win访问。

win共享,linux访问

设置好win的共享,linux默认就安装了相关samba的客户端软件

smbclient –L ip 显示共享资源
smbclient //ip/dir –U username
进入系统后遵从ftp指令
把共享资源挂在上:
smbmount //ip/dir /mntdir –o username=administrator  \\该指令已经取消了
可以使用 mount –t cifs –o username=xxx,password=xxxxx //ip/dir /mntdir  \\文件类型smbfs也没有了。

linux共享,win访问

rpm –ql samba  \\查看装了啥,可能回头去看显示不出来,加个 | head –n 显示指定行数的内容
插入:寻找某个命令是哪个包装得:
which command  \\得到所在路径
rpm –qf //path  \\得到那个软件包
按照这个方法可以找到sambapasswd是跟谁有关。

创建用户:
首先创建系统用户:useradd
再创建samba账户:smbpasswd
/etc/samba中的smb.conf是服务器的主配置文件,查询smb.conf的有效部分(其它配置文件查询也可用此法):grep -v "^#" /etc/samba/smb.conf | grep -v "^;"
输出结果(含一些注释掉但需要配置的内容):
[global]
        workgroup = MYGROUP  \\工作组名称,可以向win靠拢
        server string = Samba Server Version %v  \\
        log file = /var/log/samba/%m.log  \\日志文件位置,每个客户机的日志分别存在与客户机同名的日志中
        max log size = 50  \\日志文件最大为50k,单位是k
        printcap name = /etc/printcap
        dns proxy = yes
        cups options = raw
        security = user  \\用户级安全,需要输入用户名和密码。share表示全开,user需要用户名和密码,server由其它服务器进行身份认证,domain指定win域控验证用户名和密码
插入samba帐号管理:独立的/etc/samba/smbpasswd文件保存帐号和加密口令,首次创建samba用户会自动产生,需要有与其同名的系统帐号,口令可以不同,建议不需要登陆系统的samba帐号不设置系统口令。smbpasswd –a/d/e/x 添加/禁用/启用/删除
        passdb backend = tdbsam
        load printers = yes
        cups options = raw
[homes]
        comment = Home Directories  \\用户的家目录
        browseable = no  \\不可浏览他人家目录
        writable = yes   \\可写

[printers]
        comment = All Printers
        path = /var/spool/samba
        browseable = no
        guest ok = no
        writable = no
        printable = yes
[public]
;       comment = Public Stuff
;       path = /home/samba  \\共享目录
;       public = yes  \\任何人都能访问
;       writable = yes  \\可写
;       printable = no  
;       write list = +staff
;       only guest = yes  \\后加的,所有用户都映射成nobody,产生的文件也会更改属主
write list = +name \\成员可写
testparm指令可以检测smb.conf配置
需要注意的是:目录的权限分别由服务器和文件系统双方面限制。

启动samba:
/etc/init.d/smb  \\启动脚本
service 的名字 smb
启动服务发现有两个服务:SMB MMB,通过ps –aux | grep mb 查看其关系
smbstatus可以查看当前samba的服务状态

扩展内容:
valid users = xx xx \\只有xx可以访问目录


swat管理
安装samba-swat软件包。
配置文件在/ext/xinetd.d/swat,选项only_from=ip可以限制控制端,端口901
配置完的内容会立即生效。
-----------------------------------------------------------------------------------------------------------

[color="Red"]NFS

主要用到的配置文件是/etc/exports,默认情况下该文件是空的,可以自行编写,如:
/public *(ro,async)
/tmp 192.168.248.0/255.255.255.0(rw,async)
/home 192.168.248.0/255.255.255.0(rw,async)


检查portmap是否启动
启动nfs
使用exportfs检查NFS共享情况

客户端挂在:
mount ip:/public /mnt

NFS和NIS结合:

修改客户机fstab文件:
ip:/home/ /home nfs defaults 0 0
重新启动后,系统自动加载NIS服务器上的home目录到本地home,域用户登录也有家目录。
如果有同名情况发生,可以为NIS专门建立特定的目录,与home有却别即可。
 楼主| 发表于 2010-6-25 13:56:01 | 显示全部楼层
DNS

配置DNS:
将DNS指向自己。确保安装了bind和caching-nameserver的软件包,后者默认是不安装的。
本来应该使用的配置文件是/etc/named.conf,但是安装了caching-nameserver后配置文件变成了named.caching-nameserver.conf
全局配置:
options {
        listen-on port 53 { 127.0.0.1; };  \\改为服务器IP
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";  \\区域数据文件所在目录
        dump-file       "/var/named/data/cache_dump.db";  \\域名缓存文件的数据库
        statistics-file "/var/named/data/named_stats.txt";  \\解析统计文件
        memstatistics-file "/var/named/data/named_mem_stats.txt";

        // Those options should be used carefully because they disable port
        // randomization
        // query-source    port 53;
        // query-source-v6 port 53;

        allow-query     { localhost; };  \\改为any,否则其它客户端不能查询
        allow-query-cache { localhost; };  \\改为any,否则其它客户端不能查询
};

根区域设置在/etc/named.rfc1912.conf中
zone "." IN {
        type hint;  \\默认区域,根区域
        file "named.ca";  \\根区域文件
};
正向:
zone "localhost" IN {  \\正向解析
        type master;  \\区域的主服务器
        file "localhost.zone";  
        allow-update { none; };
};
反向:
zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "named.local";
        allow-update { none; };
};

创建测试域:
按照上面的结构创建测试区域thanatos.org:
zone "thanatos.org" IN {
        type master;
        file "thanatos.org.zone";
        allow-update { none; };
};

zone "248.168.192.in-addr.arpa" IN {
        type master;
        file "thanatos.org.rev";
        allow-update { none; };
};
建立正向区域文件:
/var/named/thanatos.org.zone和thanatos.org.rev:
$TTL    86400  \\生成周期,缓存中保存的时间
@               IN SOA dns1.thanatos.org.   (dns的完整域名)   root.thanatos.org. (管理员的邮箱)(
                                        42              ; serial (d. adams)\\序列号增加以表示更新,否则辅助域名服务器不知道更新
                                        3H              ; refresh\\刷新时间
                                        15M             ; retry\\主不发送,辅助重试
                                        1W              ; expiry\\如果长期无结果,1周后过期
                                        1D )            ; minimum \\最小缓存保存时间

                IN NS           dns1.thanatos.org.
                IN NS           dns2.thanatos.org.
                IN MX   5       mail.thanatos.org.
dns1            IN A            192.168.248.10
dns2            IN A            192.168.248.11
www             IN CNAME        dns1.thanatos.org.
ftp             IN CNAME        dns2.thanatos.org.
mail            IN CNAME        dns2.thanatos.org.

$TTL    86400
@               IN SOA  dns1.thanatos.org.      root.thanatos.org. (
                                        42              ; serial (d. adams)
                                        3H              ; refresh
                                        15M             ; retry
                                        1W              ; expiry
                                        1D )            ; minimum
        IN      NS      dns1.thanatos.org.
        IN      NS      dns2.thanatos.org.

10      IN      PTR     dns1.thanatos.org.
10      IN      PTR     www.thanatos.org.
11      IN      PTR     dns2.thanatos.org.
11      IN      PTR     ftp.thanatos.org.

配置结束后测试配置文件:named-checkconf named.caching-nameserver.conf和named.rfc1912.conf,没有问题
检查区域文件:named-checkzone thanatos.org /var/named/thanatos.org.zone和rev,没有问题
需要复制zone和rev文件到/var/named/chroot//var/named/,/var/named下的文件建立连接就可以了。
重新启动服务,进行测试。主服务配置结束。

辅助域名服务器配置:
type 从master变成slave,文件也放在slave目录下。还需要指明master的地址,可以是多个。寻找的文件名必须和主服务器一样。反向同。
副的nameserver可以指向自己。
zone "thanatos.org" IN {
        type slave;
        file "thanatos.org.zone";
        masters { 192.168.248.10; };
};

zone "0.0.127.in-addr.arpa" IN {
        type slave;
        file "thanatos.org.rev";
        masters { 192.168.248.10; };
};
失败原因:
/var/named及其下属相关目录一定要注意named的写权限。
主DNS配置的
view localhost_resolver {
        match-clients      { localhost; };  //一定要修改为any,否则不允许客户端
        match-destinations { localhost; };
        recursion yes;
        include "/etc/named.rfc1912.zones";
};

转发DNS
修改全局配置文件,在option中添加:
forward only;
forwarders { 192.168.248.10; };
去掉其它zone。

部分转发:
在named.rfc1912.conf中对需要转发的zone的type进行修改:
type forward;
forward only;
forwarders { 192.168.248.10; };

委派:
当子DNS服务器有新的记录而父没有时,可以再相关的子zone文件中添加上子的NS记录,但子的地址并不为父所致,所以还要添加上子的A记录。比如ny在11上,在10上无法解析ny,不用forward:
ny IN NS dns.ny.thanatos.org \\把NY的记录转发给dns.ny来解析
dns.ny IN A 192.168.248.11  \\找到NY的所在地址

dns查询

nslookup后,set type=mx,可以查看某个域的mx记录,set type=a,查看mial.thanatos.org的a记录。

dig
dig @192.168.248.10 thanatos.org NS  \\查询某域的全部NS记录
dig @a.root-server.net . NS > /var/named/named.ca  \\这个文件产生的方法

-----------------------------------------------------------------------------------------------------------------
Apache+LAMP

安装:Apache、mysql和php默认都可以直接安装,而且主意安装的时候选择各自互相支持的扩展及库。可以直接使用rpm进行安装,简单方便,也可以使用源码进行编译安装,灵活性强。实验采用rpm包安装,不再赘述。

为了能实现Apache支持php,需要对Apache的配置做修改。
/etc/httpd/conf/httpd.conf,修改以下几项:

确保支持php
AddType application/x-httpd-php .php \\让Apache知道运行php
确保页面目录的位置正确,默认是/var/www/html
然后建立php测试页面,比如在目录下编写index.php文件,内容是:
<?php
phpinfo();
?>
然后重启Apache,访问页面,会出现php的信息,证明实验成功。

mysql安装完毕后可以修改用户及口令:
mysql –u root –p
输入口令,进入到mysql控制界面,输入指令
show databases;
会看到已有的数据库,说明mysql运行正常。

安装phpbb:
下载phpbb完整包,解压缩到/var/www/html下,页面打开后会进入安装页面,进行自动探测,多半都是目录权限问题。请修改:
chown nobody.nobody –R *  \\递归修改所属主、组
默认情况下系统还需要安装php-mysql、php-pdo和php-gd组件才能保证php和mysql以及论坛更多功能。
一路按照提示安装即可,安装结束后删除页面根目录下的install,否则打开主页一片空白。
--------------------------------------------------------------------------------------------------------------------------------------------
VSFTP

安装配置等就不多说了。主要讲讲Solaris里没有的pam部分。
要创建虚拟用户用于系统登录必须要创建一个用户-口令文本文件:
比如logins:
mike
pwabcd
john
pw1234
要在偶数行写口令。
然后生成认证文件:
db_load –T –t hash –f logins /etc/vsftpd/login.db  \\一定是生成一个db文件,如果没有db_load命令可用,检查是否安装了db4以及它的utils包。
并修改其权限为600。

建立PAM配置文件:
/etc/pam.d/vsftpd.vu
auth required /lib/security/pam_userdb.so db=/etc/vsftpd/login  \\和数据库文件名一样,但没有.db。下同
account required /lib/security/pam_userdb.so db=/etc/vsftpd/login

再创建虚拟用户和设置权限:
useradd –d /home/ftpsite virtual
chmod 700 /home/ftpsite

修改VSFTP配置:
guest_enable= yes
guest_username=virtual
pam_service_name=vsftpd.vu

完毕后重启FTP服务,经过测试,虚拟账户可以登录。

为虚拟帐户划分权限:
在vsftpd.conf中增加:user_config_dir=/etc/vsftpd_user_conf  \\提前创建该目录
在其中创建与虚拟用户同名的文件,并进行编辑:
anon_world_readable_only=no
anon_upload_enable=yes
anon_mkdir_write_enable=yes
anon_other_write_enable=yes

虚拟ftp服务器
大的思路就是创建虚拟的网络接口,然后这个接口用在某个特定的应用上。
ifconfig eth0:0 ip
netconfig –d eth0:0
创建虚拟ftp服务器目录:
mkdir –p /var/ftp2/pub1
映射到本地用户:useradd –d /var/ftp2 –M ftp2  \\M是不为用户创建主目录
然后修改vsftpd.conf,listen_address=ip,复制成/vsftpd_site.conf,ftp_user=ftp2
---------------------------------------------------------------------------------------------------------
sendmail

配置好网卡并检查相应软件包的安装,再修改dns,增加邮件域:
zone “thanatos.org” IN  {
  type master;
  file “thanatos.org.zone”;
  allow-update { none; };
};
修改主机名为:mail.thanatos.org  \\用dns,就不改hosts了
生成thanatos.org的zone文件
SOA mail.thanatos.org
mail IN A 192.168.248.10
IN MX 5 mail.thanatos.org
启动DNS服务。检查一下:nslookup进入,set type=mx,thanatos.org后得到域中邮件服务器信息。

检查软件包sendmail、m4和sendmail-cf是否安装。进入/etc/mail
修改sendmail.mc,搜索127找到了监听端口,全改0。搜索TRUST_AUTH,把注释去掉,开启发信认证。保存退出。
修改access,增加192.168.248.0 RELAY。
生成配置:makemap hash access.db < access
修改local-host-names,增加thanatos.org。
m4 sendmail.mc > sendmail.cf  \\生成新的CF文件
创建系统用户:useradd mailtest1 –s /sbin/nologin  \\禁止该用户登录系统
useradd mailtest2 –s /sbin/nologin
编辑/etc/aliases,为用户起别名:ceshiyonghu: mailtest1
jituanyonghu: mailtest1 , mailtest2
然后执行:newaliases
启动sendmail服务器,进行测试。可以在/var/mail下看到。以上为smtp配置。

检查dovecot是否安装。编辑配置文件/etc/dovecot.conf。
去掉protocols的注释。
重启该服务,客户端可以收邮件了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 13:59:55 | 显示全部楼层
路由和防火墙

启路由转发:echo 1 > /proc/sys/net/ipv4/ip_forward
/etc/rc.d/rc.local
或者修改:/etc/sysctl.conf

服务器配置好各个网卡地址,就不费事了。
route add –net 192.168.x.x 255.255.255.0 gw 192.168.x.x
route add default gw x.x.x.x

iptables:
有5个链,实为5个检查点:路有前、转发、路由后、入站、出站。
三个规则表:filter包过滤、nat地址转换、mangle流量整形等。
特别指出reject会给对方反馈,而drop不予反馈。
不指定表明的操作默认是过滤表。
system-config-securitylevel-tui  \\傻瓜配置工具

以ftp为例:
开启vsftp
iptabless –L  \\检查当前规则链,空的
iptable –A INPUT –i eth0 –s 192.168.248.0/24 –j REJECT  \\禁止本网段所有连接
再查看规则链,并测试。如果是ssh管理的当场就歇菜了……

单服务器防护:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -j DROP

网关服务器:
iptables –t nat –A POSTROUTING –s 192.168.248.0/24 –o ppp0 –j MASQUERADE  \\ADSL出外网经过地址伪装,外网ip地址不确定时

目标地址转换:
iptables -t nat -A PREROUTING -d 192.168.248.11 -p tcp -dport 80 -j DNAT --to 192.168.248.10

更多iptables内容参见网络安全笔记。
http://www.linuxsir.cn/bbs/thread369994.html
-----------------------------------------------------------------------------------------------------------
squid

必须有完整的域名,hosts可以,DNS也可以

首次运行初始化:squid –z
服务缺省端口3128,主配置文件/etc/squid/squid.conf。
http_port是工作端口,cache_mem缓存大小,cache_dir工作目录,文件系统ufs,/var/spool/squid缓存目录,100缓存大小,16一级子目录数量,256二级子目录。
http_access allow localhost \\允许访问权限
http-access deny all  \\拒绝全部
localhost和all都要在acl中定义
acl all src 0.0.0.0/0.0.0.0
acl localhost src 127.0.0.1/255.255.255.255
配置文件有详细的说明,合理规划好ACL是重点。

配置透明**:
透明**必须是网关。
重点配置文件中的以下内容:
httpd_accel_host virtual  \\支持虚拟主机
httpd_accel_port 80  \\只接受80口
httpd_accel_with_proxy on \\支持缓存
httpd_accel_uses_host_header on  \\支持主机头
重定向iptables –t nat –A PREROUTING –i eth0 -s 192.168.248.0/24 –p tcp --dport 80 –j REDIRECT --to-port 3128

反向**(web服务器加速):
主要配置:
http_port 80
httpd_accel_host 192.168.248.10  \\真正后台
httpd_accel_port 80
httpd_accel_single_host on \\单个主机
httpd_accel_with_proxy on
httpd_accel_uses_host_header off
http_access allow all \\允许所有人访问,主意查找所有的deny all




教程剩余的ssh、l2tp、tcpwrapper讲的都太粗,而且都很简单,不再写。下面进行iptables的详细讲解。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 14:00:35 | 显示全部楼层
[Linux防火墙].(Linux.Firewalls.Attack.Detection.and.Response.with.iptables,.psad,.and.fwsnort)(美)拉什.中文高清PDF版——阅读笔记

第一章 简介

iptables和netfilter的区别:netfilter是一个Linux的项目,提供一个框架,iptables使用netfilter建立防火墙功能。

每一条规则应用于一个表中的一个链,每条链是一个规则集。

表是一个大类的描述,包括了filter、nat、mangle和raw。



2.4以后的内核基本上都已经开启了netfilter,但是基本上都被精简了,需要通过编译内核让必要的子系统启用。完整安装的linux所用内核文件在/usr/src下,执行命令make menuconfig可以开启tui进行配置。

找到位置network-networking option-network packet filtering framework。其中比较关键的配置项是core netfilter configuration和ip:netfilter configuration。保存退出后通过grep “_NF_” .config和grep NETFILTER .config来检查配置项。

内核编译才用LKM方式更方便和安全,可以使用rmmod命令去掉任意的模块从而避免存在安全漏洞的模块。但是这样做的结果和可能让入侵者直接加载一个黑客用模块,从而避免系统发现他的所有行为。

编译过程:
make
su -
Password:
mount /boot
cd /usr/src/kernel/xxxxxx
make install && make modules_install
我在make的时候出现“没有规则可以创建“init/built-in.o”需要的目标“init/main.o””错误,原来是因为没有下载内核源码包的缘故。
如果使用grub引导系统还需要编写grub文件以使系统通过新的内核启动。
title linux-2.6.x.x
root (hd0,0)  \\boot所在分区
kernel /boot/vmlinuz-2.6.x.x root=/dev/hdax  \\根分区所在
然后重启 shutdown -r now

以上完成了内核的支持工作,还需要安装用户层程序:http://www.netfilter.org/project ... ables-1.4.8.tar.bz2

CentOS自带的是1.3.5版本,现在安装最新版。
首先./configure,然后执行make KERNEL_DIR=/usr/src/kernels/2.6.18-194.3.1.el5-i686 BINDIR=/sbin LIBDIR=/lib  \\分别指明内核位置以放置C头文件,还有二进制文件以及库文件放置的位置。
然后make install KERNEL_DIR=/usr/src/kernels/2.6.18-194.3.1.el5-i686 BINDIR=/sbin LIBDIR=/lib
为确定成功安装,查看iptables的版本:iptables -V  \\如果之前有旧版本会比较麻烦,可以rpm -e xxx --nodeps强制删除,否则关联一堆。

阅读本书可以参照网址:http://www.cipherdyne.org/LinuxFirewalls,该网址还配有原文中所用拓扑图。

[IMG]https://qkzabg.bay.livefilestore.com/y1m-ajBeGNcu92bwQVe5IgV8xIM9y7NDio646tSUTEKDR-DC4zXI8fZc_ny3A6clgQchWdpMq3s21pDPSck5LztloXX4fco_ZrUGqbwGcyuQkYIQOJAyuk7QcExKI22C1VaOvKU7udeRR6C8Gbzpg7Y6Q/LF_default_network_thumb[1].png?download&psid=1[/IMG]

策略需求:

DNS
FTP
NTP
SSH
SMTP
HTTP/HTTPS
whois查询
其它通信应被拒绝,从内部起的会话都应该被跟踪,同事防火墙提供nat功能。防火墙允许内部用户ssh,其它地方不行,除非有fwknop。防火墙接收内外网的icmp回显请求,其它丢弃。要有日志记录和丢弃规则,对扫描有记录。

为方便查找,贴出选项含义:
  
[IMG]https://qkzabg.bay.livefilestore.com/y1mwTxayi9_OOOk3OAqM-5K-eCfZ39GKeAgW6ti7u9r8TNCL9mOYgZfh-tVwbn6PN2WcP1QMICsefdvKFSQ7NGbrF7uY3C_wsUueLjji9Ur_5lEtXA5D_AAa_0UK6vagWJAQtXEp-iII0WWEKr3YeetoA/image_thumb[1]%2036940D0A.png?download&psid=1[/IMG]

[IMG]https://qkzabg.bay.livefilestore.com/y1maONypNiMSrvgeqzIBRIboPqeN5Lu0WxoAdoDBkS60e75kWePCDhekOCsgWqTMvTx9aG7KEww_wZy-vLdvnhVQ91KJh7YzvCUdyn3TrcEXPt18BD1Vkx4OlSrddKbabYq6LO0liF0EKSPOlfFOj2hjg/image_thumb[4].png?download&psid=1[/IMG]

从网站摘录完整的脚本:


#!/bin/sh
#
#############################################################################
#
# File: iptables.sh
#
# Purpose: To build a basic iptables policy with default log and drop rules.
# This script was written for the book "Linux Firewalls: Attack
# Detection and Response" published by No Starch Press.
#
# Copyright (C) 2006-2009 Michael Rash (mbr@cipherdyne.org)
#
# License (GNU Public License):
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
#
#############################################################################
#
# $Id: index.html 2813 2010-07-11 13:20:26Z mbr $
#
IPTABLES=/sbin/iptables  \\说明iptables和modprobe的执行文件位置
IP6TABLES=/sbin/ip6tables
MODPROBE=/sbin/modprobe
INT_NET=192.168.10.0/24  \\定义内网地址和掩码
### flush existing rules and set chain policy setting to DROP
echo "[+] Flushing existing iptables rules..."  \\去掉所有自带策略,并全部置为丢弃
$IPTABLES -F
$IPTABLES -F -t nat
$IPTABLES -X
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
### this policy does not handle IPv6 traffic except to drop it.
#
echo "[+] Disabling IPv6 traffic..."
$IP6TABLES -P INPUT DROP
$IP6TABLES -P OUTPUT DROP
$IP6TABLES -P FORWARD DROP
### load connection-tracking modules  \\加载连接跟踪
#
$MODPROBE ip_conntrack
$MODPROBE iptable_nat
$MODPROBE ip_conntrack_ftp
$MODPROBE ip_nat_ftp
###### INPUT chain ######  \\iptables是ip层上的,所以ARP管不了,默认下开启了mac地址扩展,可以根据mac过滤ip
#
echo "[+] Setting up INPUT chain..."  \\无效链接丢弃并记录,有效链接允许
### state tracking rules
$IPTABLES -A INPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options
$IPTABLES -A INPUT -m state --state INVALID -j DROP  \\突然到达的fin都会触发无效
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT  \\连接两端,或者从源触发的目的回包是已建立或相关
### anti-spoofing rules  \\防欺骗
$IPTABLES -A INPUT -i eth1 -s ! $INT_NET -j LOG --log-prefix "SPOOFED PKT "
$IPTABLES -A INPUT -i eth1 -s ! $INT_NET -j DROP
### ACCEPT rules  
$IPTABLES -A INPUT -i eth1 -p tcp -s $INT_NET --dport 22 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT  \\特别指定--syn和state new是因为new状态的触发不一定是syn,这里可以过滤所有的非syn链接从而保证new确实是受到请求的。
### default INPUT LOG rule
$IPTABLES -A INPUT -i ! lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options
### make sure that loopback traffic is accepted
$IPTABLES -A INPUT -i lo -j ACCEPT
##############################################################################################
###### OUTPUT chain ######  \\按照功能需求进行设置,不详解
#
echo "[+] Setting up OUTPUT chain..."
### state tracking rules
$IPTABLES -A OUTPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
### ACCEPT rules for allowing connections out
$IPTABLES -A OUTPUT -p tcp --dport 21 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 43 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 4321 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
### default OUTPUT LOG rule
$IPTABLES -A OUTPUT -o ! lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options
### make sure that loopback traffic is accepted
$IPTABLES -A OUTPUT -o lo -j ACCEPT
##############################################################################################
###### FORWARD chain ######
#
echo "[+] Setting up FORWARD chain..."
### state tracking rules
$IPTABLES -A FORWARD -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options
$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
### anti-spoofing rules
$IPTABLES -A FORWARD -i eth1 -s ! $INT_NET -j LOG --log-prefix "SPOOFED PKT "
$IPTABLES -A FORWARD -i eth1 -s ! $INT_NET -j DROP
### ACCEPT rules
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 21 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 22 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 25 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 43 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT  \\将任何http、https和dns查询以及icmp回显放行
$IPTABLES -A FORWARD -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 4321 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p udp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p icmp --icmp-type echo-request -j ACCEPT
### default LOG rule
$IPTABLES -A FORWARD -i ! lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options
##############################################################################################
###### NAT rules ######  \\实现NAT转发,把不同的服务请求转发到各自目标,并允许内网访问外网
#
echo "[+] Setting up NAT rules..."
$IPTABLES -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 192.168.10.3:80
$IPTABLES -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j DNAT --to 192.168.10.3:443
$IPTABLES -t nat -A PREROUTING -p udp --dport 53 -i eth0 -j DNAT --to 192.168.10.4:53
$IPTABLES -t nat -A POSTROUTING -s $INT_NET -o eth0 -j MASQUERADE
###### forwarding ######  \\启用路由转发
#
echo "[+] Enabling IP forwarding..."
echo 1 > /proc/sys/net/ipv4/ip_forward
exit
### EOF ###


题外话:iptables怎么实现NAT的?http://www.netfilter.org/documen ... NAT-HOWTO.html#toc1  \\文字编码调成繁体中文。

原文经过整理后如下:

1.Introduction

亲爱的读者﹐欢迎您﹗

您将要探索的是引人入胜(有时蛮恐怖)的NAT(Network Address Translation)世界﹐同时﹐您甚至可以把这份HOWTO当成Linux 2.4核心及以后版本的精确指南呢。

在Linux 2.4里面﹐有一个叫`netfilter'的东东﹐它是专门撕裂(mangling*)封包的。在它再上一个层级﹐就是提供NAT功能的了﹐则是完全由以往的核心实作而成的。

(译者注﹕很奇怪﹐原作者用mangle这一词﹐似乎在过往的中文文件中都没碰到过﹐查过好多字典都不知道怎么翻译好。这里暂时勉强用‘撕裂’这个词代替﹐不过后面我就不尝试翻译这词了﹐让读者自己去理解吧。)

2.官方的网站和通信论坛何处觅﹖

目前有三个官方网站可供浏览﹕

感谢Filewatcher(http://netfilter.filewatcher.org).

感谢The Samba Team and SGI (http://www.samba.org/netfilter).

感谢Harald WeltE (http://netfilter.gnumonks.org).

而官方的netfilter邮件论坛﹐则可以到这里看﹕http://www.netfilter.org/contact.html#list

2.1何为Network Address Translation?

一般来说﹐在网络上封包从其来源(比方您家中的计算机)出去﹐然后到达目的地(比方www.gnumonks.org)﹐会经过许许多多个不同的连接(links)﹕就我所在的澳洲来说就大约有19个之多。没有任何一个连接会真的去更改您的封包﹕他们仅仅是将之传送出去而已。

假如其中一个连接会做NAT的话﹐然后它们就会更改那些经它而过的封包之来源或目的地地址。诚如您能想象得到的﹐这并非系统被设计成这样的﹐而是NAT所做的手脚而已。通常要做NAT的联机会记住它如何mangled封包的﹐然后当响应封包从另一方向过来的时候﹐然后就反过来mangling那个响应封包﹐所以所有东西都工作起来了。

2.2为什么我要做NAT呢﹖

在完美的世界里﹐您无需这样做啦。在目前来说﹐还是有其理由的﹕

用modem拨接上网

大多数的ISP在您连上去的时候只会给您一个单一IP地址。您喜欢的话﹐以任何来源地址把封包送出去都行﹐但只有响应到这个来源地址的封包?nbsp;可以回到您那里。如果您想用多台不同主机(例如家中网络)透过该连接上internet的话﹐那您就要NAT了。

这也就是今天NAT最常用之处﹐而在Linux世界最为人知的就是所谓的`masquerading(封包伪装术)'了。我称之为SNAT﹐因为您改变了第一个封包的source(来源)地址的缘故。

多重服务器

有时候﹐您会想去改变那些进入您网络的封包之路向。这最常是因为(如上述)您只有一个IP地址﹐但您却想让别人能够连接到`真实'IP地址后面的主机去。如果您重写这些内送封包的目的地址﹐这样您就可以管理它们了。

一个常见的变动是负载分担(load-sharing)﹐也就是在一组机器上面为封包做映对(mapping)的动作。这类型的NAT﹐在以前的的Linux版本中也就被称为port-forwarding。

透明**(Transparent Proxying)

有时候﹐您或许想要每一个经过您的Linux主机的封包送至主机本身的一个程序去。这就需要进行透明**的动作了﹕一个**就是一个位于您的网络和?nbsp;部网络的程序﹐为彼此双方负起沟通的任务。而所谓的透明﹐则是因为您的网络甚至无须知道在和一个**对讲﹐当然了﹐除非**不再工作了吧。

Squid可以配置成这样的工作方式﹐这就是在过往的Linux版本中所谓的重导向(redirection)﹑或透明**了。

3.两种类型的NAT

我将NAT分为两种不同的类型﹕Source NAT(SNAT)与Destination NAT(DNAT)

Source NAT就是您将改变第一个封包的来源地址﹕例如﹐您为传入的联机做caching的动作。Source NAT永远会在封包传出网线之前就做好post-routing的动作。封包伪装(Masquerading)就是一个SNAT特例。

Destination NAT就是您将改变第一个封包的目的地地址﹕例如您要为传出的联机做caching的动作。Destination NAT永远会在封包从网线进入之后就马上做好pre-routing的动作。Port forwarding﹑负载分担﹑以及透明**﹐都属于DNAT。

4.从2.0到2.2核心的快速转变

非常抱歉﹐假如您仍然忙于从2.0(ipfwadm)到2.2(ipchains)的转型的话。不过﹐这也是个喜?nbsp;参半的消息啦。

首先﹐您可以轻易的一如往昔地使用ipchains和ipfwadm。要这样做的话﹐您需要将最新的netfilter套件中的`ipchains.o'或`ipfwadm.o'核心模块加载。它们是相互排斥的(您应已获警告了)﹐同时也不能和其它netfilter模块同时整合在一起。

一旦其中一个模块被加载﹐您就可以如常使用ipchains和ipfwadm了﹐但也有如下一些变化啦﹕

用ipchains -M -S﹐或是ipfwadm -M -s作伪装逾时将不再有效。因为逾时设定已经移至新的NAT牯c中﹐所以这里也就没什么所谓了。

在伪装列表中显示的ini seq﹑delte﹑和previous delta字段﹐将永远为零。

同时归零(zeroing)和列示记数器(counter)的`-Z -L'已无作用﹕记数器将不能再归零了。

Hacker们仍要留意之处﹕

您现在可以捆绑61000-65095之间的埠口﹐而无需理会您是否使用封包伪装技术。在过去﹐封包伪装程序会把此值域内的所有东西捕获进来﹐所以其它程序就不可用之了。

至于(尚未成文之)getsockname破解﹐在过去﹐透明**程序可以找出那些不再有效联机之真正目的地。

至于(尚未成文之)bind-to-foreign-address破解﹐同样尚未实作﹔这在过去用以完善透明**的构想。

4.1救命啊﹗我只想要封包伪装而已﹗

没错﹐这也是大多数朋友之需。如果您用PPP拨接获得的动态IP(如果您不了解的话﹐那您应该是了)﹐您或许只想单纯告诉您的主机让所有来自您内部网络的封包﹐看起来如来自该PPP拨接主机一样。

# Load the NAT module (this pulls in all the others).

modprobe iptable_nat

# In the NAT table (-t nat), Append a rule (-A) after routing

# (POSTROUTING) for all packets going out ppp0 (-o ppp0) which says to

# MASQUERADE the connection (-j MASQUERADE).

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

# Turn on IP forwarding

echo 1 > /proc/sys/net/ipv4/ip_forward

注﹕您这里并没做任何封包过滤﹕如要的话﹐请参考 Packet Filtering HOWTO﹕将NAT和封包过滤合并起来就是了。

4.2那ipmasqadm怎么了﹖

这个其实取决于使用者而已﹐所以我并不是很为向后兼容问题而担心。您可以单纯使用iptables -t nat做port forwarding的动作。例如﹐在Linux2.2您或许已经这样做了﹕

# Linux 2.2

# Forward TCP packets going to port 8080 on 1.2.3.4 to 192.168.1.1's port 80

ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80

而现在﹐如此则可﹕

# Linux 2.4

# Append a rule pre-routing (-A PREROUTING) to the NAT table (-t nat) that

# TCP packets (-p tcp) going to 1.2.3.4 (-d 1.2.3.4) port 8080 (--dport 8080)

# have their destination mapped (-j DNAT) to 192.168.1.1, port 80

# (--to 192.168.1.1:80).

iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to 192.168.1.1:80

假如您想让这条规则同时修改本机联机的话(如﹐即使在NAT主机本身﹐要连接1.2.3.4的8080埠口之telnet联机﹐会帮您连接至192.168.1.1的80埠口)﹐您就可以插入相同的规则至OUTPUT链中(它只适用于本机传出的封包)﹕

# Linux 2.4

iptables -A OUTPUT -t nat -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to 192.168.1.1:80

5. 控制哪些要NAT

您需要建立一些NAT规则﹐来告诉核心哪些联机要改变﹐同时如何去改变它们。要做到这点﹐我们需要一个非常多用?nbsp;的iptables工具﹐同时指定`-t nat'选项告诉它去修改NAT表格。

NAT规则的表格含有三个列表叫做`chains'﹕每一条规则都按顺序检查﹐直到找到一个相符的比对。该三个链就叫做PREROUTING(对Destination NAT来说﹐因为封包首先是传入的)﹑POSTROUTING(对Source NAT来说﹐因为封包是离开的)﹑以及OUTPUT(对Destination NAT来说﹐是指那些由本机产生的封包)。

假如我够艺术天份的话﹐下面的图示将准确仿真出上面所说的概念。

    _____                                                      _____

     /    \                                                      /      \

PREROUTING -->[Routing ]----------------->OSTROUTING----->

   \D-NAT/        [Decision] \S-NAT/

                           |                                         ^

                           |                                      __|__

                           |                                    /         \

                           |                                  | OUTPUT|

                           |                                    \D-NAT/

                           |                                         ^

                           |                                         |

                             --------> Local Process ------

于前述的每一点﹐当一个封包通过我们要查看的相关联机之时﹐如果它是一个新建联机﹐我们查看它在NAT表格里对应的链﹐看看能对之做些什么动作。而由此获得的答案就应用于该联机将来的所有封包。

5.1用iptables做简单的选择

iptables具有如后所列的许多标准选项。所有那些带双减号的选项都是可以缩写的﹐只要iptables仍可将之与其它可能的选项区分开来就行。如果您的核心以模块形式来支持iptables﹐您就需要首先加载ip_tables.o﹕`insmod ip_tables'。

这里﹐最重要的一个选项是表格选择选项﹕`-t'。对于所有的NAT操作﹐您会想用`-t nat'来表示NAT表格。第二个重要的选项是以`-A'增加一条新规则至链的末端(如﹕`-A POSTROUTING')﹐或以`-I'插入至前端(如﹕`-I PREROUTING')。

您可以指定您要做NAT的封包来源地址(`-s'或`--source')与目的地(`-d'or`--destination')。这两个选项后面可以后接一个单一的IP地址(如﹕192.168.1.1)﹐或一个名称(如﹕www.gnumonks.org)﹐或一个网 ... 0/255.255.255.0)。

您也可以指定要比对的传入(`-i'或`--in-interface')和传出(`-o' or `--out-interface')界面﹐但哪一个界面可以指定则取决于您要将规则写入哪一个链去﹕对于PREROUTING﹐您可以选择传入界面﹐但对于POSTROUTING(以及OUTPUT)﹐您可以选择传出界面。如果您不小心用错了﹐iptables就会给您一个错?nbsp;。

5.2关于挑选哪些封包来mangle的细节

我前面已经说过﹐您可以指定来源和目的地地址。如果您省略来源地址的选项﹐那么就泛指任何来源。如果您省略目的地地址﹐则泛指所有目的地地址。

您还可以指定一个特定协议(`-p' or `--protocol')呢﹐例如TCP或UDP﹕只有这些协议的封包?nbsp;符合该规则。其主要原因是﹐指定tcp或udp协议可以允许更多选项﹕尤其是`--source-port'与`--destination-port'选项(缩写为`--sport'与`--dport')。

这些选项可以让您指定只有哪些特定来源和目的地埠口的封包?nbsp;符合该规则。这在您要重导web请求(TCP port 80或8080)但又怕影响其它封包的时候﹐就很好用了。

这些选项必须接在`-p'选项的后面(这会在为该协定加载共享函式库时有副作用)。您可以使用端口口号码﹐或者是在/etc/services档中的名称。

所有这些您能选择的封包之不同?nbsp;质﹐都详细列在那个详细得有点恐怖的manual page中了(man iptables)。

6.谈谈要怎样Mangle封包

现在﹐我们知道如何去挑选那些我们要mangle的封包。为了要完善我们的规则﹐我们需要准确无?nbsp;的告诉核心﹐什么?nbsp;是我们要对封包做的。

6.1SourceNAT

您想要做Source NAT﹐是要去将联机的来源地址换成别的什么的。这就要在它最后要送出去之前﹐于POSTROUTING链中完成了﹔这是一个非常重要的细节﹐因为它意味着所有在Linux主机本身上的其它东西(routing,packet filtering)都只看见那个还没改变的封包。同时﹐这也就是说﹐`-o'(传出界面)选项可以派上用场了。

Source NAT是用`-j SNAT'来指定的﹐同时﹐`--to source'则指定一个IP地址﹑或一段IP地址﹑以及一个可配选的埠口或一段值域的埠口(仅适用于UDP和TCP协议)。

## Change source addresses to 1.2.3.4.

# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

## Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6

# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6

## Change source addresses to 1.2.3.4, ports 1-1023

# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

封包伪装(Masquerading)

有一个Source NAT之特例﹐叫做封包伪装﹕它只用于动态分配的IP地址﹐例如标准的拨接(如果用静态IP地址﹐则使用前述之SNAT)。

您无需明确地将masquerading放进来源地址那里去﹕它将会使用封包传出界面作为来源地址。但更重要的是﹐如果该连接(link)断掉的话﹐那么联机(connections﹐无可避免的将失掉)也会被忘掉﹐当联机用新的IP地址回来的时候就会有问题了。

## Masquerade everything out ppp0.

# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

6.2 Destination NAT

一旦封包进入﹐会由PREROUTING链完成处理﹔也就是说﹐除了该主机自己的其它东西(诸如﹕路由﹑封包过滤)都将封包看成要送到`真正'目的地。另?nbsp;﹐那个`-i'(传入界面)选项也可以在这里使用。

需要修改本机产生的封包之目的地的话﹐那么OUTPUT链就可以用上了﹐不过这并不常碰到。

Destination NAT必须以`-j DNAT'来指定使用﹐同时用`--to destination'选项指定一个IP地址﹑或一段IP地址﹐以及可以配选一个埠口或一段埠口值域(只能用于UDP和TCP协定上面)。

## Change destination addresses to 5.6.7.8

# iptables -t nat -A PREROUTING -i eth1 -j DNAT --to 5.6.7.8

## Change destination addresses to 5.6.7.8, 5.6.7.9 or 5.6.7.10.

# iptables -t nat -A PREROUTING -i eth1 -j DNAT --to 5.6.7.8-5.6.7.10

## Change destination addresses of web traffic to 5.6.7.8, port 8080.

# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j DNAT --to 5.6.7.8:8080

## Redirect local packets to 1.2.3.4 to loopback.

# iptables -t nat -A OUTPUT -d 1.2.3.4 -j DNAT --to 127.0.0.1

重导向(Redirection)

在Destination NAT有一个特别的情形﹕它是一个简单的便利﹐完全等同于给传入界面地址做DNAT一样。

## Send incoming port-80 web traffic to our squid (transparent) proxy

# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128

6.3 进一步的映对(Mappings)

还有许多 NAT 上面的解决方案是大多数人无需用到的。这里不妨和那些有兴趣的朋友探讨一下﹕

同一范围内的复合地址(Multiple Addresses)之选择。

如果您已经指定了一段 IP地址﹐而IP地址的使用选择是基于机器所知联机目前最少使用之IP。它可以提供最原始的平衡负载(load-balancing)。

建立空NAT映对

您可以使用`-j ACCEPT'目标来让一个联机通过﹐而绕过NAT的处理。

标准的NAT行为(Behaviour)

默认的行为是在用户制定的规则限制内﹐尽可能少的改变联机。换而言之﹐非不得已不要重映对(remap)埠口。

绝对来源埠口映对

如果其它联机已经被映对到新的联机﹐就算对于一个无需NAT的联机来说﹐来源埠口的转换有时或是必须绝对存在的。让我们假设一个封包伪装的情形﹐这已经非常普遍了﹕

1.一个网页联机由一台192.1.1.1的机器从port 1024建立﹐要连接到www.netscape.com port 80。

2.它被封包伪装主机以其自己的IP地址(1.2.3.4)进行伪装。

3.该封包伪装主机尝试由1.2.3.4(它的?nbsp;部界面地址)port 1024来做一个网页联机至www.netscape.com port 80。

4.然后NAT程序改变第二个联机的来源埠口为1025﹐所以这两个联机不至于相冲(clash)。

当这个绝对来源映对存在之时﹐埠口被拆分为三个等级﹕

512以下的埠口

512到1023之间的埠口

1024以上的埠口

任何一个埠口都不会被绝对映对到不同的等级去。

当NAT失效时会怎样﹖

如果没有办法如用户要求那样独一无二地映对联机﹐那么联机就会被挡掉。当一个封包不能够界定为任何联机的时候﹐结果也一样﹐因为它们可算是畸形的﹐或者是该机器内存耗光了﹐诸如此类。

复合映对﹑重迭﹑和相冲(clash)

您可以设定NAT规则在同一个范围之上映对封包﹔NAT程序足以聪明的去避免相冲。比方说﹐用两条规则将192.168.1.1和192.168.1.2这两个来源地址分别映对到1.2.3.4﹐是完全可行的。

再来﹐您可以映对到真实的﹑已用的IP地址﹐只要这些地址通过这个映对主机就行。所以﹐如果您获得一个网络(1.2.3.0/24)﹐但有一个内部网络使用这些地址﹐而另一个使用私有地址192.168.1.0/24﹐您就可以NAT那些192.168.1.0/24的来源地址到1.2.3.0网络之上﹐而无需担心相冲﹕

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.3.0/24

这同样适用于那些NAT主机自己使用的地址﹕这其实就是封包伪装如何工作的了(分享伪装封包地址和来自主机本身封包之`真实'地址。)

更甚者﹐您还可以映对相同的封包到许多不同的目标(targets)上去﹐而且它们都是共享的。例如﹐如果您不想映对任何东西到1.2.3.5上去﹐您可以这样做﹕

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254

改变本机产生的联机之目的地

如果本机产生的封包之目的地改变了(例如﹐用 OUTPUT 链)﹐而这样会导致封包由不同的界面送出去﹐这样来源地址也跟着变为那个界面。举例子说﹐改变一个环回(loopback)封包之目的地由 eth0送出﹐会让来源地址也由127.0.0.1变成eth0的地址﹔而不像其它来源地址映对那样﹐这是立即完成的。当然﹐所有这些映对在响应封包进入时是颠倒过来的。

7.特殊协议

有些协定是并不想要做NAT的。对于每一个这样的协议而言﹐有两个延伸设定(extension)是必须要写清楚的:一个是关于协议之联机追踪﹐另一个关于实际的NAT。

在netfilter发行套件里面﹐有一些关于ftp的现行模块﹕ip_conntrack_ftp.o与ip_nat_ftp.o。如果您把这些插入到您的核心里面(或您永久性的编译它们)﹐那么要在ftp联机上做任何种类的NAT都是可行的。如果您不这样的话﹐那您可以使用被动模式ftp﹐不过如果您要做一些动作甚于简单Source NAT的话﹐这就可能不那么可靠了。

8.NAT的一些限制(caveats)

如果在一个联机上做NAT﹐所有双向(传出和传入)的封包﹐都必须要通过NAT主机?nbsp;行﹐否则并不可靠。尤其在联机追踪程序重组碎片(fragments)的时候﹐也就是说﹐不但联机追踪会不可能﹐而且您的封包根本就不能通过﹐因为碎片会被挡下。

9.Source NAT与路由

如果您要做SNAT﹐您会想要确定经过SNAT封包所传给的主机会将响应送回给NAT主机。例如﹐如果您映对某些传出封包到来源地址1.2.3.4之上﹐那么?nbsp;部的路由器就必须知道要将响应封包(目的地为1.2.3.4)送回给该主机。这可以用如下方法做到﹕

1.如果您要在主机自己的地址(路由和其它所有运作皆正常)上面做SNAT﹐您无需做任何动作。

2.如果您要在一个在本机网络上尚未使用的地址做SNAT(例如﹐映对到在1.2.3.0/24网络上的一个可用IP 1.2.3.99)﹐您的NAT主机就需要响应关于该地址的ARP请求﹐一如它自己本身的一样﹕最简单的方法就是建立IP alias﹐例如﹕

# ip address add 1.2.3.99 dev eth0

3.如果您要在一个完全不同的地址上做SNAT﹐您就要确定SNAT封包抵达的机器能够路由回该NAT主机。如果NAT主机是它们的默认网关的话﹐是可以做到的﹐否则﹐您就要广告(advertize)一个路由(如果跑路由协议的话)﹐或是手工的在每一台参与机器上增斥竷恁C

10.在同一网络上的Destination NAT

如果您要做portforwarding回到同一个网络﹐您要确定前向和响应封包双方都经过该NAT主机(这样它们?nbsp;能被修改)。NAT程序从现在开始(2.4.0-test6以后)﹐会挡掉后面情形所产生的传出ICMP重导向﹕那些已经NAT的封包以它所进入的相同界面传出﹐而接收端服务器仍尝试直接响应到客户端(不认可该响应)。

经典的情形是内部人员尝试连接到您的`公有(public)'网站服务器﹐实际上是从公有地址(1.2.3.4)DNAT到一个内部的机器(192.168.1.1)去﹐就像这样﹕

# iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to 192.168.1.1

一个方法是跑一台内部DNS服务器﹐它知道您的公有网站的真正(内部)IP地址﹐而将其它请求转传给?nbsp;部的DNS服务器。换而言之﹐关于您网站服务器的记录会正确地显示为内部IP地址。

而另一个方法是同时让这台NAT主机将该等联机之来源IP地址映对为它自己的地址﹐我们可以像如下那样做(假设NAT主机之内部IP地址为192.168.1.250)﹕

# iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 -p tcp --dport 80 -j SNAT --to 192.168.1.250

因为PREROUTING规则是最先执行的﹐对内部网站服务器而言﹐封包就已经被定向好了﹕我们可以内定好哪个为来源IP地址。

11.感谢

首先感谢在我工作期间相信netfilter的构想并支持我的WatchGuard和David Bonn。

以及所有其他帮我指正NAT之不足的朋友﹐尤其是那些读过我的日记的。

Rusty.
-----------------------------------------------------------------------------------------------

编写完脚本后通过./iptables.sh进行启用。为了保证重启后能快速恢复,使用:
iptables-save > /root/ipt.save
cat /root/ipt.save | grep iptables-restore
测试TCP:通过内网和外网的扫描机进行TCP连接,nc -v x.x.x.x 5500,一个防火墙规定之外的端口,理论上是被drop,因为drop,所以不存在返回rst/ack,扫描端出现挂起状态。
测试UDP:使用hping -2 -p 5500 x.x.x.x,观察iptables的日志记录。
说明:在没有全部修改安全策略的情况下,针对单台设备的安全防护也是有必要的。
测试ICMP:hping -1 --icmptype echo-reply x.x.x.x
hping -1 --icmptype echo-reply x.x.x.x

配置了一个完整的初始化防火墙,第一章完。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 14:01:33 | 显示全部楼层
第二章 网络层的攻击与防御

上章回顾:根据版本的变化,1.4.8版本的iptables对于某类接口的非表示不再是-i ! eth0,而是把!挪前面,是! -i eth0。另外,用源码安装hping3会报pcap头文件错误,可以从光盘中安装pcap的lib和devel,不过make依然不能通过。后面的实验使用系统自带的1.3.5。

记录网络层首部信息:

1、记录IP选项:
上一章中所有的LOG操作都试用了 --log-ip-option,目的是记录ip选项的内容。可是做以下实验:
普通pingiptables,观察messages中关于此次icmp的记录。
使用ping -c 1 -T tsonly x.x.x.x,再次观察messages中的记录,会看到OPT选项和完整选项值,但没有解码,在后面用psad解决。

2、记录ICMP
回显请求类型8代码0,可以在log中的CODE看到。

网络层攻击包括:首部滥用、网络栈漏洞、带宽饱和

滥用网络层:
NMAP ICMP PING:在没有-p0选项的情况下,nmap会对不在同一个网段的主机发送一个目标端口80的TCP ACK进行主机发现,这个数据包字段长28,20个ip首部,8个ICMP首部。可以使用ping -s 0模拟这种情况。

IP欺骗:Nmap和hping都可以实现ip欺骗,比如nmap的ftp攻击。通过编写perl脚本也可以实现ip欺骗:
#!/usr/bin/perl -w

use NET::RawIP;
use strict;
my $src = $ARGV[0] or &usage();
my $dst = $ARGV[1] or &usage();
my $str = $ARGV[2] or &usage();

my $rawpkt = new NET::RawIP({
        ip => {
                saddr => $src,
                daddr => $dst
        },
        udp =>()}
);

$rawpkt->set({ ip => {
        saddr => $src,
        daddr => $dst },
        udp => {
                source => 10001,
                dest => 53,
                data => $str,
}
});

$rawpkt->send();
print '[+] Sent '. length($str)." bytes of data...\n";
exit 0;
sub usage(){
        die "usage: $a <src> <dst> <str>";
}

该脚本运行需要perl的相关包,不了解而没有成功运行。具体失败解决办法参考:http://netwalk.blog.51cto.com/173717/128210

IP分片:生成分片数据的黄金标准是fragroute工具:http://www.monkey.org。

低TTL:使用traceroute或者tcptraceroute产生的包具有低ttl值。组播地址的TTL通常也是1。

分片和TTL联合攻击:一个攻击包分F1、F2、F3三个分片发送,目标主机在一个基于主机的IDS后和一个路由器后。生成一个F2',去掉有效载荷且TTL=1,发送F1+F2'+F3,F2'会被路由丢弃,主机收到F1+F3,攻击者再发送F2,F2不会被IDS认定为危险数据包,攻击者收到F1+F2+F3并重组。可以参考http://www.icir.org/vern/papers/bro-CN99.html。

smurf攻击:向一个网络发送伪造源地址的回显请求广播,从而对伪源地址造成DOS攻击效果。如果不在网络上设置阻止广播地址的ICMP回显请求(no ip directed-broadcast),会遭到攻击。攻击源码:http://www.phreak.org/archives/exploits/denial/smurf.c。  \\可能需要翻墙吧。

网络层过滤回应:
iptables -I INPUT 1 -s x.x.x.x -j DROP
iptables -I OUTPUT 1 -d x.x.x.x -j DROP
iptables -I FORWARD 1 -s x.x.x.x -j DROP
iptables -I FORWARD 1 -s x.x.x.x -j DROP

网络层阈值回应:
iptables -I INPUT -1 -m limit --limit 10/sec -s x.x.x.x -j ACCEPT
iptables -I INPUT -2 -s x.x.x.x -j DROP
……省略其它两个链。每秒只能接受10个关于X.X.X.X的数据包。

结合多层的回应:白名单的建立是不现实的,用REJECT拒绝目标并添加永久拒绝策略在TOR面前也无效。

第二章完。
------------------------------------------------------------------------------------------------------------------------------------
第三章 传输层的攻击与防御

记录TCP首部:



传输层的连接记录:nc -v x.x.x.x 15104  \\发起一个15104的tcp连接,得到的日志记录会有明确的连接信息。如果要记录tcp序号和确认序号:
iptables -I INPUT 1 -p tcp --dport 15104 -j LOG --log-tcp-option --log -tcp-sequence

记录UDP首部:



原有的策略只可记录基本信息:
echo -n “aaaa” | nc -u x.x.x.x 5001

传输层攻击分三种:耗尽连接资源、首部滥用、传输栈漏洞利用。

滥用传输层:
1、端口扫描:大范围的扫描只能激活IDS,可以使用Nmap的-D来增加多个伪扫描源以隐蔽自己。
2、TCP端口扫描:以Nmap为用例,均使用-P0来禁止存活探测。一下测试使用Nmap5.30beta为例。


TCP connect()扫描:nmap -P0 -sT x.x.x.x
查看日志:grep SYN /var/log/messages | tail -n 1

TCP SYN或半开放扫描:防止SYN扫描可以添加:
iptables -I INPUT 1 -d x.x.x.x -p tcp --tcp-flags RST RST -j DROP
3.x版本的NMAP在构建SYN包时还没有MSS字段,而在新版本中是有的。通过
nmap -P0 -sS x.x.x.x
grep SYN /var/log/messages | tail -n 1
可以看到这种SYN包和connect()产生的SYN包想必,opt内容少了很多。

FIN XMAS NULL扫描:
通过Nmap的fin扫描都会被防火墙以INVALID丢弃,故会有这样的显示:
nmap -P0 -sF x.x.x.x
All 1000 scanned ports on x.x.x.x are open|filtered
grep FIN /var/log/messages | tail -n 1  \\会看到INVALID丢弃

ACK扫描:
nmap -P0 -sA x.x.x.x  \\因为存在状态跟踪,所以数据包可以进入TCP协议栈
grep ACK /var/log/messages | tail -n 1  

Idle扫描:
以一个服务不忙的主机作为傀儡,然后伪造SYN以傀儡地址发送给目标,目标返回SYN/ACK给傀儡,傀儡返回RST,从而让IP ID变化,通过跟踪IP ID以判断目标主机情况。所以在目标主机上看到的日志和傀儡直接SYN扫描的结果一致。

端口扫射:nmap -P0 -p 22 -sS x.x.x.x/x 直接找一个网段的所有开SSH的服务器。

TCP序号预测攻击:通过猜测或跟踪序号从而插入当前会话中。如http://osvdb.org/ref/04/04040-SlippingInTheWindow_v1.0.doc。通过RST数据包破坏思科路由器的BGP对等回话。

SYN洪泛:伪造源地址SYN包给目标从而耗尽资源。
iptables -I FORWARD 1 -p tcp --syn -m limit --limit 1/s -j ACCEPT

传输层回应:

RST/ACK和RST:最后一个包有ACK,则返回无,否则相反。如果端口无服务则RST/ACK,如果端口关闭则RST。
iptables -I INPUT 1 -p tcp --dport 5001 -j ACCEPT
nmap -P0 -sS -p 5001 x.x.x.x
tcpdump -i eth0 -l -nn port 5001  \\得到一个RST数据包且有非零值,因为扫描端发送的SYN包
nmap -P0 -sA -p 5001 x.x.x.x
tcpdump -i eth0 -l -nn port 5001  \\得到的RST没有ACK

中断一个已有连接——向iptables主机发送字符串后被中断连接:
iptables -I INPUT 1 -p tcp --dport 5001 -j ACCEPT  \\放行5001
iptables -I INPUT 1 -p tcp --dport 5001 -m string --string ”tester” --algo bm -j REJECT --reject-with tcp-rest  \\匹配tester并进行中断
nc -l -p 5001 &  \\监听5001端口。不知道为何加上-p无法执行,不加p效果一样
tcpdump -i eth0 -l -nn -s 0 -X port 5001  \\-s 0保证所有应用层数据被捕获,-X打印应用层数据
然后通过其它机器向其发送信息:echo “tester” | nc x.x.x.x 5001
通过观察tcpdump的信息,找到tester,后面会跟着一个ACK值为0的RST,因为前一个包已经含有ACK了。

SYN Cookies:在内核中开启CONFIG_SYN_COOKIES的支持后,通过echo 1 >/proc/sys/net/ipv4/tcp_syncookies开启SYN Cookies,从而节省资源。具体原理参考:

http://www.ibm.com/developerworks/cn/linux/l-syncookie/index.html

SYN Cookie原理及其在Linux内核中的实现


2004 年 9 月 01 日

本文就分别介绍一下 SYN Flood 攻击和 SYN Cookie 的原理,更重要的是介绍 Linux 内核中实现SYN Cookie 的方式。最后,本文给出一种增强目前 Linux 中 SYN Cookie 功能的想法。
概述

在目前以IPv4为支撑的网络协议上搭建的网络环境中,SYN Flood是一种非常危险而常见的DoS攻击方式。到目前为止,能够有效防范SYN Flood攻击的手段并不多,而SYN Cookie就是其中最著名的一种。SYN Cookie原理由D. J. Bernstain和 Eric Schenk发明。在很多操作系统上都有各种各样的实现。其中包括Linux。本文就分别介绍一下SYN Flood攻击和SYN Cookie的原理,更重要的是介绍Linux内核中实现SYN Cookie的方式。最后,本文给出一种增强目前Linux中SYN Cookie功能的想法。

一 SYN Flood攻击

SYN Flood攻击是一种典型的拒绝服务型(Denial of Service)攻击。所谓拒绝服务型攻击就是通过进行攻击,使受害主机或网络不能够良好的提供服务,从而间接达到攻击的目的。

SYN Flood攻击利用的是IPv4中TCP协议的三次握手(Three-Way Handshake)过程进行的攻击。大家知道协议规定,如果一端想向另一端发起TCP连接,它需要首先发送TCP SYN 包到对方,对方收到后发送一个TCP SYN+ACK包回来,发起方再发送TCP ACK包回去,这样三次握手就结束了。我们把TCP连接的发起方叫作"TCP客户机(TCP Client)",TCP连接的接收方叫作"TCP服务器(TCP Server)"。值得注意的是在TCP服务器收到TCP SYN request包时,在发送TCP SYN+ACK包回TCP客户机前,TCP服务器要先分配好一个数据区专门服务于这个即将形成的TCP连接。一般把收到SYN包而还未收到ACK包时的连接状态成为半开连接(Half-open Connection)。

在最常见的SYN Flood攻击中,攻击者在短时间内发送大量的TCP SYN包给受害者,这时攻击者是TCP客户机,受害者是TCP服务器。根据上面的描述,受害者会为每个TCP SYN包分配一个特定的数据区,只要这些SYN包具有不同的源地址(这一点对于攻击者来说是很容易伪造的)。这将给TCP服务器系统造成很大的系统负担,最终导致系统不能正常工作。

二 SYN Cookie原理

SYN Cookie是对TCP服务器端的三次握手协议作一些修改,专门用来防范SYN Flood攻击的一种手段。它的原理是,在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值。在收到TCP ACK包时,TCP服务器在根据那个cookie值检查这个TCP ACK包的合法性。如果合法,再分配专门的数据区进行处理未来的TCP连接。

从上面的介绍可以看出,SYN Cookie的原理比较简单。到实际的应用中,它有多种不同的实现方式。

三 Linux内核中的SYN Cookie实现

Linux内核中对SYN Flood有很好的防护。以下的讨论都是针对Linux2.4.20内核进行的。在每一个sock都有一个tcp_opt即这个sock的TCP选项。在tcp_opt其中有一个tcp_listen_opt,这里存储的是这个sock在LISTEN状态下时保存的一些选项,其中有一个open_request结构的数组,数组长度为TCP_SYNQ_HSIZE(512)。所有这些表示在一个sock,最多可以同时开启512个半开连接(这是在不考虑其他约束条件时的最大值,实际情况中不会达到这个值)。当这个数组满了时,新来的open_request会顶替掉一个老的open_request。这样,即使没有启动SYN Cookie,也能够在SYN Flood发生时保护系统免于瘫痪。问题是这种处理方法会在面对SYN Flood攻击时丢掉正常的TCP连接请求。SYN Cookie的作用恰恰是保证在面对SYN Flood攻击时,一方面能够拒绝非法的TCP连接请求,一方面正常连接可以被建立。

Linux内核对TCP流程的处理主要在tcp_ipv4.c文件中的函数实现。具体的,当处理TCP SYN包时,系统进入tcp_v4_conn_request函数。其中调用cookie_v4_init_sequence生成一个ISN(Initial Sequence Number)。Linux内核把它作为SYN Cookie流程中的cookie。

cookie_v4_init_sequence函数在syncookies.c文件中定义,它又调用random.c文件中的secure_tcp_syn_cookie函数。cookie的实质计算是在这个函数中进行的。

在random.c文件里给出secure_tcp_syn_cookie函数的定义之前给出两个宏,它们的定义分别为

    #define COOKIEBITS 24
    #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
    COOKIEBITS表示cookie的比特长度;COOKIEMASK是一个COOKIEBITS长的比特串,所有比特都是1。

还有两个比特串,被定义成一个__u32的二维数组

    static __u32        syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
    其中所有的比特值在secure_tcp_syn_cookie中被随机的赋予,用get_random_bytes函数。它们成为制作cookie的密钥。这两个被随机产生的比特串是整个SYN Cookie实现方案的关键。另外还有一个开关syncookie_init控制对这两个密钥的改动。

还需要指出,在文件syncookies.c中定义有一个__u16组成的表static __u16 const msstab[],这个表中保存的是一些可能的MSS(Maximum Segment Size)值。

secure_tcp_syn_cookie函数的返回值就是计算得到的ISN值,即cookie。为了描述方便,我们给出如下定义:

        tmp1 := saddr + daddr + ((sport<<16)+dport) + syncookie_secret[0]
        tmp2 := saddr + daddr + ((sport<<16)+dport) + syncookie_secret[1]
        tmp11 := HASH_TRANSFORM(tmp1[16], tmp1)
        tmp22 := HASH_TRANSFORM(tmp2[16], tmp2)
    A := tmp11[0][17]
        B := tmp22[1][17]
        sseq := ntohl(skb->h.th->seq) 这里的skb是携带TCP SYN的那个skb
count1 := jiffies/(HZ*60) 当前时间的分钟值
data1 := msstab
从前往后最后一个小于skb中携带的MSS值的值的索引(值得注意的是两个密钥在第一次被初始化后,就不会再有改动,直到系统重新启动。因此可以认为它是一个常值。)

有了上面的定义我们可以得到cookie等于

        isn := A+sseq + (count1<<COOKIEBITS) + (B+data1)&COOKIEMASK
        这个isn被赋予返回的TCP SYN+ACK包中,作为其中的ISN值。这就是cookie 的产生过程。在这个过程中,没有在本地为这个连接请求分配任何存储空间。

在TCP服务器收到TCP ACK包时,相应的要进行SYN Cookie的检查。这个检查过程在函数tcp_v4_hnd_req中的cookie_v4_check函数开始。cookie_v4_check调用cookie_check函数,cookie_check函数调用check_tcp_syn_cookie函数。

check_tcp_syn_cookie函数在random.c中定义,是与前面介绍的
secure_tcp_syn_cookie函数对应的函数,检查从TCP ACK中提取出的ISN值。

在check_tcp_syn_cookie中假定ISN的值如下

        isn := A+sseq + (count2<<COOKIEBITS) + (B+data2)&COOKIEMASK
        这里的A、B都是根据当前这个skb中的地址信息和syncookie_secret算出来的;sseq是根据这个skb中的seq值算出的。

有了上面这些值,TCP服务器就可以反算出count2和data2。理论上来说,只要这个isn是原来那个isn,应该有

count2 == count1  
data2 == data1
但是这种结论仅仅是一个理论情况。因为在TCP服务器端并没有保存原来的count1和data1,因此不能直接进行比较。TCP服务器采取的方法是:

1)计算出当前的分钟值
count3 := jiffies/(HZ*60)
用count3与count2比较,如果差值超过COUNTER_TRIES(4)分钟,则认为这个ACK包不合法。
2)看data2是不是一个合法的msstab的索引,也就是说是不是小于NUM_MSS,即(sizeof(msstab)/sizeof(msstab[0]) - 1)。如果小于,则认为这个ACK 合法,否则认为非法。

上面介绍的就是Linux内核Linux2.4.20中对SYN Cookie的实现方式。下面讨论一下它的合理性。希望得到的结论是这种方案可以有效的实现一般TCP的连接,同时可以防止SYN Flood攻击。

从上面的介绍来说,合法的TCP连接请求一定可以通过SYN Cookie流程。另一方面我们看SYN Cookie在系统受到各种SYN Flood攻击时会采取的行为。最一般的SYN Flood攻击方式是攻击者作为TCP客户机发送大量TCP SYN包而不再发送其他的包。这时SYN Cookie会为每个SYN包计算出相应的ISN值,并返回SYN+ACK包,而在本地将不分配任何存储空间,因此不会被成功攻击。

根据SYN Cookie的原理,攻击者有可能直接发送大量ACK包。这时SYN Cookie提取出每个包的isn值,并假定它有下面的格式

        isn := A+sseq + (count<<COOKIEBITS) + (B+data)&COOKIEMASK
        反算出count和data。

因为攻击者并不知道这里的A和B,因此经过反算出的count和data几乎不可能都合理,因此TCP服务器也几乎不可能为这些ACK包分配存储空间,这也就说明了SYN Cookie达到起到了抵挡SYN Flood攻击的作用。

四 SYN Cookie Firewall

从上面的介绍可以看到,Linux内核中的SYN Cookie机制主要的功能是防止本机遭受SYN Flood攻击的,但是在很多情况下,仅仅实现这样的SYN Cookie机制是不够的。如果我们要考虑的是一个网关模式的防火墙,它不仅要保护本机免受各种网络攻击,还要保护它后面的所有对外有开放TCP端口的主机免受这些攻击。比如一个局域网中有个服务器开放了FTP服务给外界,这个服务器主机就有可能遭受到来自互联网上的SYN Flood攻击。而这时的防火墙会将所有的攻击SYN包转发给受害主机。

一种杜绝这种情况的方法是SYN Cookie Firewall。它是SYN Cookie的一种扩展形式。总的来说,它是利用原来SYN Cookie的原理在内网和外网之间实现TCP三次握手过程的**(proxy)的机制。

为了方便描述,我们假定一个外在的TCP客户机C希望通过防火墙F连接到局域网中的一个TCP服务器S。

在防火墙收到来自外网的SYN包时,它并不直接进行转发,而是缓存在本地,再按照原来SYN Cookie的机制制作好一个针对这个SYN包的SYN+ACK包,注意,这个SYN+ACK包中的ack顺序号为特制的cookie值c,更重要的是这个包的的源地址被伪造成了S的地址(为了描述方便,我们这里暂时不考虑NAT等其他因素)。这样C会接收到这个SYN+ACK包,并认为是从S反馈回来的。于是C再响应一个ACK包,并认为与S的TCP连接已经建立起来。这时防火墙F收到这个ACK包,按照前面的描述的SYN Cookie原理来检查这个ACK中的ack顺序号。如果认为合法,F将本地缓存的来自C的SYN包发送给S,这时S会响应一个SYN+ACK包到C,其中也携带一个seq号, 我们设为c`。当然这个包不会到达C,而是由防火墙F截取,F根据这个包中的序列号等信息,造一个ACK包响应到S。这时的情况是:C认为自己已经与S建立了TCP连接;S认为自己与C建立了TCP连接。以后的TCP数据内容可以直接穿过防火墙F,在S和C之间交互。

[IMG]https://qkzabg.bay.livefilestore.com/y1mG-4AuLbKxE_JQ7TK5Ju6Mt_g_BWbzMDVfhj0iHr_N9TiQ8fwjxAumQl_FeSNBgtN0Ij3qZMbJgOFfEwOb1sUedM9sRlM-OUnOaaaGZZBXRXrAL8-NuEb1QDIGWoSNKZ9xMaZe1YZ4sNArxEvVZHZvQ/image002_thumb[1].jpg?download&psid=1[/IMG]

上图是SYN Cookie Firewall的工作原理,它相当于在TCP Server与TCP Client之间实现了对三次握手协议的**。第一次"三次握手"在TCP Client与防火墙之间进行,第二次"三次握手"在防火墙与TCP Server之间。在第一次"三次握手"时使用前面介绍的SYN Cookie流程。有一个问题在进行两次"三次握手"时出现了:如图所示,进行第一次"三次握手"后,TCP Client认为后续数据包的seq值从c+1开始,而进行第二次"三次握手"后,TCP Server认为后续发来的数据包的seq值从c`+1开始, c是cookie,c`是TCP Server随机产生的。c和c`几乎不可能相等,也就是说在完成上面的两个"三次握手"后,如果不进行其他操作,后续从TCP Client到TCP Server的数据包都将被认为顺序号不对而被丢掉。一种补救方法就是在防火墙本地保存一个值δ
δ = |c - c`|
利用这个差值,在每个数据包经过防火墙时,将其seq值修改一下,这样,后续的数据流量可以完美地在TCP Server和TCP Client之间传输了。

总结

现在普遍使用的IPv4协议带有很多安全上的问题,其中面对SYN Flood攻击的软弱就是一点。在不改变TCP三次握手流程的情况下,TCP Server几乎不可能有效的防范SYN Flood的攻击。要保证完全防范SYN Flood,必须修改三次握手协议。SYN Cookie是一种很有效的方法。它的思想比较简单,主要是如何具体的实现,Linux系统也提供了一种实现。作者通过研读Linux2.4.20内核中的代码,基本了解了Linux内核中实现SYN Cookie的手段,将其总结成文字,与对SYN Cookie同样感兴趣的朋友分享、交流。

关于作者

魏晋伟,通过 weijinwei@yahoo.com.cn可以跟他联系。

UDP回应:iptables -I INPUT 1 -p udp --dport 5001 -j ACCEPT
echo -n “aaaa” | nc -u x.x.x.x 5001
tcpdump -i eth0 -l -nn port 5001
会看到对方发来的UDP数据会被unreachable返回,因为5001上没有服务监听。
如果想在有服务的端口上返回这样的数据可以如下设置:
iptables -I INPUT 1 -p udp --dport 5001 -j REJECT --reject-with icmp-port-unreachable
测试:nc -l -u -p 5001 &
echo -n “aaaa” | nc -u x.x.x.x 5001
tcpdump -i eth0 -l -nn port 5001
返回结果会和没有服务监听效果一致。

如果针对web服务器进行攻击,可以临时的限制该攻击IP的数据访问:
iptables -I FORWARD 1 -s x.x.x.x -p tcp --dport 80 -j DROP
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 14:02:22 | 显示全部楼层
第四章 应用层的攻击与防御

iptables字符过滤:
iptables -I INPUT 1 -p tcp --dport 5001 -m string --string "tester" --algo bm -m state --state ESTABLISHED -j LOG --log-prefix "tester"  \\algo bm使用Boyer-Moore算法,优于kmp算法Knuth-Morris_Pratt。state ESTABLISHED只针对已建立连接进行过滤。
进行检测:nc -l -p 5001
echo “tester” | nc x.x.x.x 5001
tail /var/log/messages | grep tester
发现已经被进行了日志记录

匹配不可打印的应用层数据:
不可打印出来的ASCII字符,如日元,在ISO 8859-9字符表中。
iptables -I INPUT 1 -p udp --dport 5002 -m string --hex-string “|a7a7a7a7a7a7a7a7a7a7|” -algo bm -j LOG --log-prefix “YEN ”
nc -u -l 5002
perl -e ‘print “\xa7”x10’ | nc -u x.x.x.x 5002
tail /var/log/messages | grep YEN
看到已经过滤出来的包,而且可以通过将a7导出来看看是否能正常显示,其实是非ASCII显示字符。

应用层攻击包括:利用变成错误而进行SQL注入、缓冲区益处等,利用信任关系进行钓鱼和跨站,耗尽资源

滥用应用层:
用户进行越权操作的防范,参考Snort的签名,可以创建iptables规则:
iptables -I FORWARD 1 -p tcp --dport 80 -m state --state ESTABLISHED -m string --string “/etc/shadow” --agle bm -j LOG --log-prefix “ETC_SHADOW ”

缓冲区益处攻击是对那些没有边界检查的函数的调用引起的:strcpy()、strcat()、sprintf()、gets()、scanf(),对malloc()、calloc()这样的函数从堆中分配的内存区域管理不善也会导致。
如何编写缓冲区溢出攻击可以参考http://insecure.org/stf/smashstack.html
以及黑客之道:漏洞发掘的艺术
如果对方通过连续的字符填充来进行缓冲区攻击,可以通过如下进行过滤:
iptables -I FORWARE 1 -p tcp --dport 443 -m state --state ESTABLISHED -m string --string “AAAAAAAAAAAAAAAAAAAAAAAAAAAA” -j LOG --log-prefix “SSL OVERFLOW ”
虽然填充字符可能发生改变,但有的蠕虫是自动填充,在某些情况下该方法还有效。
如果针对FTP服务器的chown命令进行溢出攻击,可以:
iptables -I FORWARD 1 -p tcp --dport 21 -m state --state ESTABLISHED -m string --string “site” --algo bm -m string --string “chown” --algo bm -m length --length 140 -j LOG --log-prefix “CHOWN OVERFLOW ”  \\140的长度考虑了ip的20和tcp的20,只选取100的长度。

注入攻击:例如一个结束的单引号跟随两个“-”,可以对其余的内容注释掉。
iptables -I FORWARD 1 -p tcp --dport 1433 -m state --state ESTABLISHED -m string --hex-string “’|00|” --algo bm -m string --hex-string “-|00|-|00|”  --algo bm -j LOG --log-prefix “SQL INJECTION COMMENT ”  \\这种过滤无论是否出现内容顺序倒置都可以被触发,如果正常应用可以倒置将增加误报
注入的更多内容可以参考more_advanced_sql_injection.pdf

大脑灰质攻击(好可怕的名字啊!):
钓鱼攻击。比如在邮件中存在如下代码:
<a href=”http://x.x.x.x/sys/” on MouseMove=”window.status=’https://www.citibank.com/us/cards/index.jsp’;return true;” onMouseout=”window.status=’ ’”>here</a>  \\如果鼠标移到链接上则显示正确的花期银行的jsp,点击则实际进入了x.x.x.x的钓鱼页面。
针对这种钓鱼要把握黑站点地址和被模仿页面两个因素,只能在事后进行增加规则:
iptables -I FORWARD 1 -p tcp --dport 25 -m state --state ESTABLISHED -m string --string “http://x.x.x.x/sys/” --algo bm -m string --hex-string “window.status=|27|https://www.citibank.com” -j LOG --log-prefix “CITIBANK PHISH ”  \\|27|是单引号
后门和击键记录。后门程序会对入侵者身份认证,通过这点进行规则匹配:
iptables -I FORWARD 1 -p tcp -m state --state ESTABLISHED -m string --hex-string “RemoteNC Control Password|3A|” --algo bm -j LOG --log-ip-options --log-tcp-options --log-prefix “FSSNIFFER BACKDOOR ”  \\只针对FsSniffer这种后门攻击进行匹配检测

加密和编码:支持gzip的http服务器或其它编码都会对IDS产生屏蔽作用。而URI这类编码则有相应的签名而无需解码。ssl这类加密本身也有一些和加密无关的漏洞而看到有效载荷。

应用层回应:
更多的考虑是通过传输和网络来回应,应用本身更多的是禁用账户和中断连接。
------------------------------------------------------------------------------------------------------------------
第五章 端口扫描攻击检测程序psad简介

全称:PortScan Attack Detector。前身是Bastille-NIDS项目,可以分析ipchains和iptables的日志。

特性:和fwsnort结合使用可以检测60%以上的snort规则。psad可以被动检测扫描主机指纹甚至精确到SP。还有详细电子邮件、系统日志警报、基于危险级别阈值自动阻止IP、集成whois支持、DShield报告等

下载地址:www.cipherdyne.org/psad/download \\rpm下载的无法安装,使用源码包安装,过程中一路默认。

psad主要用perl编写,kmsgsd和psadwatchd是C语言编写。
psad需要的模块有:Date::Calc IPTables:arse Net::Ipv4Addr IPTables::ChainMgr Unix::Syslog
psad有三个守护进程:psad、kmsgsd和psadwatchd,都在/usr/sbin目录中,配置文件在/etc/psad/psad.conf。
/etc/psad/archive目录中是现有配置文件副本。
主工作目录是/var/log/psad
目录的安排,原来unix的文件位置都是由FHS所定义的。www.pathname.com/fhs

启动psad后应该有三个进程psadwatchd、psad、kmsgsd,不过不知道为啥kmsgsd没有起来,<可能是我安装的时候有个只针对某种还有指定字符的日志进行审计一项选错了>,后来发现,从2.1.3版本往后psad直接分析messages文件,所以不用管道了。如果syslog文件有变化,则配置psad的配置文件中IPT_SYSLOG_FILE即可。
kmsgsd通过/var/lib/psad/psadfifo读iptables日志,写入/var/log/psad/fwdata让pssad分析。psad会重新配置syslog,让kern.info的信息也会写入管道。
psad自动验证本地iptables的INPUT和FORWARD是否有默认LOG和DROP,通过/urs/sbin/fwcheck_psad脚本检查。禁用检查使用--no-fwcheck关闭。也可以在psad配置文件中的ENABLE_FW_LOGGING_CHECK变量设置为N来禁用。脚本用的IPTables:arse Perl模块。





说明,极复杂的那段脚本没有执行成功,不知道原因。

老版本的psad安装后会修改/etc/syslog.conf增加kern.info到管道的配置。新版本不需要。

psad集成whois系统,可以直接对目标ip进行查询/usr/bin/whois_psad

psad配置:每个配置项就参考官方文档http://www.cipherdyne.org/psad/docs/config.html

需要注意的是:
敏感性:通过DANGER_LEVEL可以按照数据包的多少定义安全级别,5级为最高。面对攻击者的扫描,按照CHECK_INTERVAL的配置psad会定时进行日志分析,而SCAN_TIMEOUT会设置一个默认1小时的时间,在这个时间范围内没有达到危险级别则不会报警,而攻击者可能采用慢速扫描,那么就可以通过ENABLE_PERSISTENCE来忽略SCAN_TIMEOUT,一旦达到指定数据包级别就报警。PORT_RANGE_SCAN_THRESHOLD定义的1就是至少两个端口被扫才触发报警,采用的是P2-P1的计算方法。上限3万。IGNORE_PORTS可以定义忽略协议(TCP/UDP)/端口号。如果不修改iptables而放行某个协议可以配置IGNORE_PROTOCOLS。IGNORE_LOG_PREFIXES可以忽略一些前缀项。
报警:EMAIL_ALERT_DANGER_LEVEL定义目标IP达到哪个危险级别就发邮件,而MIN_DANGER_LEVEL需要低于电邮的级别,这个级别会记录在/var/log/psad/ip目录中。SHOW_ALL_SIGNATURES会把可疑IP的所有可疑通信都列举出来从而产生一个冗长的邮件,如果禁用掉在CHECK_INTERVAL中也会有新触发的签名。ALERT_ALL如果是Y则目标IP平级的二次扫描也会遭到报警,否则就是晋级才报警。如果一个IP反复报警那就通过EMAIL_LIMIT来限制邮件发送数量的上限。ALERTING_METHODS可以定义noemail不发邮件或nosyslog不记录日志或者ALL二者都有。如果只想分析特定的前缀日志项就设置FW_MSG_SEARCH配上特定前缀。
联动:SNORT_SID_STR会检查fwsnort产生的iptables规则,过程是匹配SID前缀。如果ENABLE_AUTO_IDS打开则会自动修改iptables进行回应。
备份:psad重启会把/var/log/psad中的所有IP子目录都删除,那么通过IMPORT_OLD_SCANS可以再重启后也能保存并导入之前的数据。如果有DShield可以打开ENABLE_DSHIELD_ALERTS进行数据导入。

黑白名单/etc/psad/auto_dl:规则是——ip地址/network 危险级别 可选协议/可选端口
修改后的Snort规则/etc/psad/signatures:会有psad特有的属性,如id和危险级别。
/etc/psad/snort_rule_dl:定义一个sid并对应的危险级别,谁触犯直接给谁扣上。
/etc/psad/ip_options:如果日志有ip选项可以进行匹配检查,比如跟有G的traceroute进行源站选路,规则——选项值 长度(可变为-1) ipopts参数 说明。
指纹/etc/psad/pf.os:psad自动导入,如果没有可以通过kill或者psad -H挂起后导入。

第五章完。

所用示例文件在www.cipherdyne.org/LinuxFirewalls

-----------------------------------------------------------------------------------------------------------
第六章 psad运作:检测可以流量

PSAD扫描端口:
测试使用拓扑不变,iptables策略默认。为了防止nmap傻等不会归来的SYN/ACK或RST/ACK,nmap使用--max-rtt-timeout选项,具体时间设置可以先通过ping来检测一下。
TCP connect()扫描:nmap -sT -n 192.168.248.10 --max-rtt-timeout 500
扫描结束后发现没有端口开放,奇怪的是我在iptables上开放了80却没有报出来,我又起了http依然没有报80口开放,难道是没有扫描么?我指定了端口再次测试,反馈80口被filtered了,奇怪的现象,和原书不匹配。通过查看messages文件可以看到psad报出的日志,含有扫描的源目地址,端口范围,旗标,协议和包数,还有psad的签名定义的安全级别。在老版本中因为存在将日志写入管道后进行分析的过程,所以存在数量急剧增加后可能丢失分析目标的情况,老的机制是写入psad的fwdata文件中,目前没有这个文件了,所以单独的psad存储信息也不知道应该上哪里去看,貌似比messages本身的信息更丰富。不过也可以通过mail来看详情。

TCP SYN或半开放扫描:从理论上看它和connect扫描效果无异,但存在很多不同。connect是从本机的TCP栈出去的官方数据包,而SYN包都是nmap自己构造的,所以要有root权限。使用:namp -n x.x.x.x --max-rtt-timeout 500就是默认的syn扫描。通过日志可以看到syn和connect的很多不同:len,十以内比connect少16个字节,因为官方数据有很多选项;connect发出的ttl都是一样的,而syn的在37-60之间随机;syn的window有好多档次,connect用的标准5840;4.02之前的nmap没有TCP选项,即OPT,所以很容易让人发现扫描,新版本的将选项减少从而缩短OPT,只发送了最大段长度,而正经的包还有时戳、无操作(NOP)等。
TCP FIN XMAS NULL扫描:三者不同处再与TCP标记的组合,合法的通信中FIN是说没数据传输了,准备中断了,是一个使用普遍的标志位。为了区别扫描和正常数据传输,可以通过匹配连接状态来区分哪些是扫描。FIN扫描会看到FIN标志位,俄日XMAS和NULL和FIN类似,XMAS不但是FIN还有URG PSH FIN组合,而NULL是什么都没有。

UDP扫描:因为没有负责的连接关系,所以UDP扫描的结果并不一定准确。psad通过目标发送UDP数据包的量和端口范围来判断,前提是假设所有的连接都是恶意的。DANGER_LEVEL和PORT_RANGE_SCAN_THRESHOLD的值可以用来控制。扫描结果中无法判断是否真的有服务器和每个端口关联。

psad警报与报告:

电子邮件:在邮件中会针对攻击的详细信息给出汇报,还有whois的查询信息。
syslog:psad启动的时候会导入一些相关信息,可以通过service psad restart后查看messages,有一些imported相关的信息。另一类信息就是psad检测到的扫描信息,包含源目地址、旗标和其它相关信息。第三类信息就是psad创建的用于阻拦信息的iptables规则和一些回应信息。

第六章完。


-----------------------------------------------------------------------------------------------------------------
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 14:03:04 | 显示全部楼层
第七章:psad高级主题:从签名匹配到操作系统指纹识别

psad的攻击识别文件在/etc/psad/signatures中,可以直接查看。每个指纹中含有一些关键信息:
psad_id:签名的唯一ID号,10000开始。psad_dl:危险级别。psad_dsize:有效载荷减去20后的值,可以使:><三种,字节为单位。psad_derived_sids:跟踪Snort签名的sid值。psad_ip_len:不减去20的dsize。

检测攻击举例:
ipEye是一个端口扫描器,不如nmap。匹配它的sig是622,特定的SYN序号是“seq:1958810375”。为了检测序列号,需要iptables增加 --log-tcp-sequence
LAND攻击是针对win构造源目一致的包。规则527,就是检查源目地址是否同样sameip。所以无需过多设置。避免误报针对本地环回接口不放在测试中。
TCP0口流量是非正常的,可以直接检测出来。nmap3.5以后就支持了。
TTL0虽然不能过3层但可以发给二层连接的设备。匹配ttl就可以检测到。
Naptha拒绝服务是典型的DOS攻击,SYN洪泛。匹配ID275,特征是IP ID413,TCP序号6060842。
源站选路分宽松和严格两种。源站选路信息在IP首部,选项字段39字节,3个字节附加信息,还要有一个目的地址,所以只有8个路由地址空间,如果使用严格的类型攻击几乎无效,只能选择宽松的源站选路。使用--log-ip-options进行查找,检测OPT字符串,宽松源站选路的选项号是131,十六进制为83,在OPT中包含83的就会被报告。
windowsMessenger*出广告的特征是UDP,端口1026~1029,长度大于100字节。

psad签名更新:
更新在http://www.cipherdyne.org/psad/signatures发布,可以通过psad --sig-update进行在线升级。

识别操作系统指纹:
所谓的操作系统指纹识别实际上是针对网络栈的识别。
常见的是Nmap主动识别,通过构建TCP首部选项部分的相应和对已关闭UDP数据包相应ICMP端口不可达消息的特征。Xprobe是一个不错的工具,Nmap有时可能要构造1400多个数据包来探测,Xprobe要少得多。
p0f识别:通过目标数据中的TCP SYN或SYN/ACK检查IP和TCP手部的:分片位、TTL、MSS、SYN数据包总长、TCP选项值顺序、TCP窗口大小判断。相比较p0f是通过libpcap实现判断,iptables直接通过--log-tcp-options或许所需信息。
iptables获取的OPT是长长的一串十六进制,进行解码后可以得到签名匹配信息。020405B40402080A0B00CE790000000001030302:02是最大段长度,04是长度,05B4是1460,NOP误操作,选择性确认OK,时戳188338970,窗口扩大因子是2。

DShield:统计全球提交的安全事件数据http://www.dshield.org。默认psad是开启发送的,发送可以使匿名的也可以是注册过ID的,可以在psad的配置文件中写入。通过psad --Status可以查看详细的信息,各种topX。

取证模式:使用psad -A可以对现有的iptables日志进行分析,输出结果类似--Status,给出各种top。如果想要修改分析文件路径加上-m就可以。

debug:如果psad --debug,那么会在屏幕上显示从日志到发送报警邮件的全部详情。-D可以把本地配置和本地系统Perl语言的版本显示在STDOUT上,--fw-dump可以显示当前iptables策略。

第7章完。

------------------------------------------------------------------------------------------------------------
第八章 使用psad实现积极回应

与入侵防御的方式相反,积极响应并不能阻拦一开始的攻击,而是通过匹配规则后增加拦截机制。比如2004的witty蠕虫通过4000发送UDP数据,如果禁掉UDP4000就会阻拦ICQ业务。两个因素:反馈ICMP端口不可达没有意义,攻击已经进入目标系统;伪造源地址的攻击让拦截无效甚至会破坏网络连通性。如果采用积极的回应,那么就要对已建立连接进行攻击过滤,即使可能产生误报也比对网络产生毁灭性攻击来得好。

和TCPWRAPPERS相比,psad可以重新配置hosts.deny,但是这样不好:1、tcpwrappers只能支持配置支持它的程序,iptables可以让攻击者都不能到达目标系统IP协议栈。2、tcpwrappers只能保护本地的,iptables可以修改forward链保护转发。

经过配置的psad可以通过增加iptables规则来阻拦攻击。比如
nmap -sS -P0 -n x.x.x.x可能首次发现有目标端口开放,但是五秒后规则加入了,再次扫描发现所有端口都是过滤的。查看psad增加的规则可以使用psad --fw-list。增加后的规则有默认的时限,通过psad --Status查看剩余时间。

如果已经知晓目标系统的而一些端口,如80,可以针对80单独进行版本扫描:
nmap -sV -P0 -p 80 -n x.x.x.x。但是如果使用无效链接扫描如FIN就会被过滤掉-sF。

如果对方使用nmap -sS -P0 -S x.x.x.x -e eth0 -n x.x.x.x伪造一个扫描地址那psad将会添加一个无效的过滤规则。多尝试几次攻击甚至有可能成功,所以并不能积极的回应,这样只能暴露我们的回应机制。应该配置成自动回应已建立TCP连接的恶意流量。

psad提供命令行和socket接口进行调控。比如通过psad --fw-list查看psad的列表,对于指定的IP可以通过--fw-block-ip来添加规则,通过--fw-rm-block-ip可以删除规则。--flush可以清空所有psad的规则。

程序可以调用/var/run/psad/auto_ipt.sock与psad守护进程通信。

最后的结论是尽量少用积极的回应。

第八章完。
------------------------------------------------------------------------------------------------------------------
第九章 转换Snort规则为iptables规则

使用fwsnort的原因:作为现有IDS/IPS的补充,可以通过分片重组避免分片攻击,占用资源少,线内回应可以为内部修复争取时间。

fwsnort对:ack icmp_id icmp_seq id sameip seq window都没有对应的过滤选项,所以对snort的转换也因此不能达到100%。

转换对比:
※ content和uricontent都可以通过string匹配来实现,但是针对uri的编码fwsnort并没有完全转换,这样会遗漏攻击。
※offset是指从第几个字节开始检查,匹配的是--from
※depth是匹配深度尝试,和上面类似但相反,对应的是--to
※iptables在针对以上两个计算的时候都是以MAC地址字段开始的。
※distance是模式匹配之间略过的字数,但fwsnort可以使用一个近似值。如果想禁止该转换可以用fwsnort --strict。
※within是后续匹配需要在某个范围内发生,和上面一样,只能给出个大概值。
※flags为TCP首部定义搜索条件,iptables可以用--tcp-flags进行匹配。匹配两个参数:要检查的标记列表和实际必须设置的标记为,比如ALL SYN,FIN
※itype和icode用于匹配ICMP首部中8位ICMP类型和代码字段数值。比如类型值大于10且代码值小雨30的ICMP消息:itype: >10; icode:<30。iptables不支持这种匹配,但是默认的snort也没有使用itype的规则,使用icode的规则不超过1%。
※ttl可以用-m --ttl-lt value -m --ttl-eq value -m ttl-gt value实现。
※tos是IP首部服务类型位,用-m tos --tos value来实现。
※ipopts对IP首部进行搜索,主要针对源站选路的企图。iptables不支持首部字段检测,但通过ipv4options可以进行基本检测:
-m ipv4options --lsrr  检查宽松
-m ipv4options --ssrr  检查严格
-m ipv4options --rr     检测记录路径选项,可用于绘图
比如iptables -A INPUT -p ip -m ipv4options --rr -j LOG --log-prefix “RECORD ROUTE IP OPTION”
需要开启CONFIG_IP_NF_MATCH_IPV4OPTIONS
※dsize对数据包有效载荷进行检查,针对的是应用层部分存在的字节数。比如dsize:>500或者dsize:400<>500。iptables也不能支持,但可以根据length获取一个近似值,但包括了网络、传输和应用层的总长度。但IP首20、UDP和ICMP回显8、TCP30(20固定10选项)可以推导出一个近似值。需要开启CONFIG_IP_NF_MATCH_LENGTH。在fwsnort.conf文件中的AVG_IP_HEADER_LEN和AVG_TCP_HEADER_LEN可以定义IP和TCP首部平均长度。
※ip_proto将Snort规则限制只针对IP首部中协议字段为256个值中的某个数据包,在/etc/protocol中指定了。但snort并不能解码,只是对有效载荷进行分析。snort可以通过!<>进行匹配,iptables不支持范围指定,但支持!取反。
※flow是snort与stream预处理器结合使用,可以对重组的TCP流应用状态和方向匹配。snort检查TCP首部标志位,但可以被伪造的ACK欺骗。snort监控TCP三次握手,必须有双向数据,伪造的ACK不足以满足这个要求。而iptables可以使用连接状态-m state进行判断。
※replace可以让snort对匹配内容进行替换。如果iptables的string扩展打上了fwsnort提供的--replace-string补丁后可以进行替换,比如:iptables -A INPUT -p tcp --dport 80 -m string --string “/bin/sh” --replace-string “/abc/de” -j ACCEPT
resp用来积极回应触发签名的流量。iptables可以-j REJECT --reject-with tcp-reset或者icmp-*-unreachable(*是net、host、port)来支持。

测试:中断“/etc/passwd”的web会话:
服务器iptables -I INPUT 1 -p tcp --dport 80 -m string --string “/etc/passwd” --algo bm -j REJECT --reject-with tcp-reset
客户端:iptables -I INPUT 1 -p tcp --tcp-flag RST RST -j DROP
然后服务器nc -l 80开始监听,并tcpdump -i ethX -l -nn port 80开始抓包。客户端echo “/etc/passwd” | nc x.x.x.x 80来发送敏感信息。在服务器端可以看到大量的R,虽然客户端一直在发,但是数据包都被过滤掉了。

不支持的:
※asn1:解码ASN.1数据
※byte_jump:执行下一个匹配跳过多少字节,可以用u32来弥补
※byet_test:对特定偏移位置的数据进行数值测试,u32可以支持部分
※flowbits:明文登录协议后flowbits打上LoggedIn标签,另一个snort规则检查会先用flowbits检查标签有没有。iptables可以用CONNMARK目标和string匹配模拟,但支持不好。
※fragbits:检查是否分片了。iptables在看到连接的时候都是重组后的,要不不知道是否属于一个连接。
※isdataat:检查一个特定位置是否有数据存在。
※pcre:perl兼容的正则表达式,支持复杂匹配。但放在Linux内核中危险。
※rpc:解码RPC。iptables的rpc扩展可以支持,fwsnort是否支持未知。

第九章完

----------------------------------------------------------------------------------------------------------------------------------

第十章 部署fwsnort

新版的fwsnort可以从www.cipherdyne.org/fwsnort/download下载。
解压后安装:tar xvzf fwsnortxxxxxx   ./install。安装的过程中会询问是否升级。升级网站源为www.bleedingsnort.com
直接运行:fwsnort。可以看到长长输出,说明了每种规则成功转化、失败、可运用到当前ipt以及规则总量的数值。转化失败的规则会在/var/log/fwsnort.log中给出详细原因。另一个输出文件/etc/fwsnort/fwsnort.sh是运用到ipt的核心脚本。
fwsnort的配置文件在/etc/fwsnort/fwsnort.conf,里面定义了IP TCP头的平均长度,网络替换符,以及黑白名单,还有fwsnort新增加的跳转链插入的位置。考虑到安全因素建议fwsnort.sh脚本不安装在ipt上,因为不推荐ipt安装强解释能力程序。加固主机安全可以参考www.bastille-linux.org(不明 ... 被墙的……)
脚本文件不要执行,会有大量的错误报出来。脚本文件分成三块儿,分别是TCP连接状态与fwsnort链的定义,签名检查和日志生成,使用跳转激活fwsnort链。其中签名检查会在日志中生成详细的注释以表明这是原snort中的哪个id产生的及其原因。
fwsnort的执行可以有很多选项,看看man。比较常用的是--ipt-drop/reject来响应攻击,如果更改了配置路径要--snort-conf,如果只启用某个sid的插件可以--snort-sid。如果想快速清空生成的规则只需--ipt-flush。如果不考虑相容性可以禁用相容检查--no-ipt-sync。

测试。
检测Trin00 DDoS:启用SID237 fwsnort --snort-sid 237,然后执行脚本以在ipt中生成规则。通过测试机向ipt发送然后查看日志echo “l44adsl” | nc -u x.x.x.x 27444
grep SID237 /var/log/messages | tail -n 1
检测Linux Shellcode流量:主要测试返回流量中含有/bin/bash。匹配SID652。从外部测试perl -e 'print "\x90\x90\x90\xE8\xC0\xFF\xFF/bin/sh"' | nc 192.168.249.10 80
检测及回应Dumador木马:SID 2002763,详细匹配测试可以自己尝试从内网发起,过滤字符3次。
检测DNS高速缓存投毒:被攻陷的高级DNS向下游宣告错误的域名解析,从而让被攻击者访问有问题的域名。对应SID 2001842,特征为有系统向7sir7.com发送DNS请求。并不一定要真的访问恶意域名,perl -e ‘print “\x057sir7\x03com”’ | nc -u x.x.x.x 53即可。通过查看日志,ipt依然是转发了数据包的,因为一开始并没有设置要丢弃或者怎么处理。要丢弃这些数据包只需fwsnort --snort-sids 2001842 --ipt-drop即可。

黑白名单:白名单的规则实际上是RETURN是为了避免重量级数据包检查的资源消耗,黑名单是DROP避免任何操作。
关于FORWARD和fwsnort链的路径参考下图:

[IMG]https://qkzabg.bay.livefilestore.com/y1mFRyh7y6oFjlni2qn-u2pcFmSM7tq-gaXNnQwlyHZqoNGgTBRbxCbIOwtrOc-ow89G2SXKC0k1QtaGkHksJi5CiwZk6_R3U-w97o4LIeTjsDAuMj8MYSsWZw9T6d1N6tviy5vGX5sqUE7AbuPzlnU4A/image_thumb[1]%205D9CD036.png?download&psid=1[/IMG]

第十章完。

------------------------------------------------------------------------------------------------------------------------------------------------------

第十一章 psad与fwsnort结合

fwsnort的规则是通过iptables直接运行在内核中的,对于应用层面的报警有欠缺。将二者结合以满足应用需要。为了弄明白二者的关系,用WEB-PHP setup.php access攻击作为试验。

SID是2281,可以执行任何代码。在外部电脑上安装lynx进行命令行web浏览。通过外网访问内网web服务器,没有问题。通过snort签名查看特征,此时再次访问内网服务器的/Setup.php,得到结果是404,说明没有漏洞,因为没有运行MediaWiki。
此时用fwsnort进行检测,不跟--ipt-drop或者reject。fwsnort --snort-sid 2281,然后添加到ipt中。此时再让外网访问一次就会在ipt中留下日志记录。然后我们让psad发警报。psad的警报基础是fwsnort的日志前缀,要想解释日志就要配置psad的配置文件中SNORT_SID_STR变量,默认是SID。检查一下psad是否在运行,然后再次进行攻击测试,会看到报警邮件,内容包括全套详细信息。

如果让psad和fwsnort结合并主动回应攻击并不现实,比如使用tor后的攻击,积极响应甚至会对自己不利。限制psad只回应fwsnort检测的攻击:首先修改psad的设置,将AUTO_IDS_DANGER_LEVEL的值配上,打开ENABLE_AUTO_IDS,以后就会委托DROP规则来拦截攻击者IP。而回应攻击者也是有风险的,所以只针对已经建立连接的恶意数据,于是AUTO_BLOCK_REGEX变量为ESTAB,和fwsnor的设置一样,并开启ENABLE_AUTO_IDS_REGEX。再次测试攻击,首先重新fwsnort sid2281,然后在psad中设置拦截项为开启IDS,危险级别4,阻断时间1小时,打开ENABLE_AUTO_IDS_REGEX,阻断正则表达式AUTO_BLOCK_REGEX是ESTAB。重启psad以应用上面变更,然后再次测试攻击代码,这次没有404了,可以通过tcpdump -i ethX -l -nn port 80看幕后详细信息。攻击后ip被阻断了,通过psad --fw-list看看拦截情况,就算正常访问也不能进行了。

如果使用reject回复攻击也可以,实际调用的是NF_DROP。

metasploit是个很好用的工具,我们针对内网阻止大家使用和更新。主要依靠的是发现SSL初始化阶段,拦截自行签署式证书。对应id是900001。

psad通过fwsnort的日志产生规则实验失败了,还没有找到原因。

第十一章完。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 14:03:49 | 显示全部楼层
第十二章 端口碰撞与单数据包授权

如果对已有的安全控制措施能再增加一道安全门不是坏事,并且面对零日攻击如果能给出一个具有一定预见性,比如根据某种原理从而避免一类安全攻击的防范措施,可以很好的防护我们的系统。

端口碰撞通过关闭端口实现认证数据的通信,如果客户端想要与服务器进行通信,那么他需要产生正确的碰撞序列。端口碰撞序列可以是非加密的端口组合,也可以是经过加密处理过的。端口碰撞可以将你的服务隐藏起来,避免NMAP的发现。比如客户端要访问服务器的22口,他需要发送SYN到服务器的TCP5005,5008,1002和1050。IPT可能根据策略把所有的包都DROP了,但是服务器根据日志记录发现这是一个有效序列,于是临时改变IPT从而让访问可以通过。用于碰撞的协议可以是TCP、UDP、ICMP,并且可以在一次碰撞序列中随意组合。加密的碰撞序列:IP是32位,IP号是8位,端口号是16位,如果要让服务器允许1.2.3.4访问TCP22口,那么碰撞包可能是6(TCP),22,1,2,3,4,亦或是这些数值的16进制表示。使用Rijindael加密的最小区块是16字节,所以还要填充9个字节。将8个字节用户名作为填充,再加上一字节作为最低限度校验和。经过加密处理后的碰撞包并不能随意发送到知名端口上,这会儿增加计算负担。碰撞序列中每个字节都可以表示成一个单字节(0到255),所以指定碰撞端口是64400~64655。

端口碰撞的限制:1、网络上能够监听到碰撞序列的人都可以重新发送一次,从而进行重放攻击。已有的一些控制措施可以阻止重放攻击,但是需要客户端与服务器都保存一些状态信息,或者一次成功连接后每次都修改一下信息。2、最小数据传输率,因为TCP和UDP首部端口字段16位,如果就用这个端口作为碰撞端口,每个数据包可以传输2字节,而且要考虑传输延迟的问题,需要有一个传输延迟约定,比如半秒钟。要传递对称加密的128位块,那就要8个数据包,延迟达到4秒。3、碰撞序列和端口扫描。碰撞序列在IDS严重和端口扫描没什么区别。4、可以通过伪造碰撞包扰乱正常的碰撞,造成DOS。

为了解决这些问题,使用SPA(单数据包授权)。认证放在有效载荷中,一个MTU1514个字节,足以证明身份。SPA会在每个数据包中包含一个随机数,并且对全包进行加密,服务端收到包解密后进行md5,这就保证了任何重放攻击都会被发现。SPA使用IP有效载荷传递数据,比数据包首部的信息多得多。SPA一个数据包完成认证,避免了IDS的误判。伪造的数据包不可能破坏掉SPA,除非洪泛攻击。

SPA局限:如果一个内网通过NAT获得权限,那么全内网都可以了,这叫NAT捎带问题,可以通过Tor网络的MapAddress功能缓解。临时开启的连接会根据需要自动关闭,那么对于已经建立连接的就要通过状态跟踪来维持传输。但假定每个TCP连接都是单独的情况下,如果传输连接太多,比如http+smtp等,就会反复传递,大量的SPA会带来不便。解决这个问题使用延长客户端超时选项,虽然会降低SPA的效力。如果可以也可以将密码放在客户端本地,但这会让加密效力降低。

引用一句话说明什么是安全:如果把一封信锁在保险柜中,把保险柜藏在纽约的某个地方…,然后告诉你去看这封信。这并不是安全,而是隐藏。相反,如果把一封信锁在保险柜中,然后把保险柜及其设计规范和许多同样的保险柜给你,以便你和世界上最好的开保险柜的专家能够研究锁的装置。而你还是无法打开保险柜去读这封信,这样才是安全的。

SPA的目的就是一开始就不允许任何IP地址连接到有弱点的服务。

------------------------------------------------------------------------------------------------------------------------------------------------------


第十三章 fwknop简介

下载并安装fwknop,主要配置文件时fwknop.conf和access.conf。主要配置access.conf文件即可。比如例子中用到的配置是:
SOURCE: ANY;  \\谁给的SPA包都行
OPEN_PORTS: tcp/22;  \\对目标开放22口
FW_ACCESS_TIMEOUT: 30;  \\就开30秒
REQUIRE_USERNAME: thanatos;  \\用户名是
KEY: password;  \\用户密码是password,这适用于SPA对称加密情况
GPG_DECRYPT_PW: gpg’s password;  \\用户的密钥密码是,这适用于非对称加密的情况
GPG_HOME_DIR: /root/.gnupg;  \\gpg的根目录
GPG_REMOTE_ID: 123123123;  \\客户端证书ID
GPG_DECRYPT_ID: 123123123;  \\本地证书ID

一个SPA包含有随机数据16字节,用户名,时间戳、软件版本、模式、访问指令、命令字符串、数据包MD5、服务器认证方式。

测试:在ipt上安装好fwknop,起服务以及ssh。客户端nc -v x.x.x.x 22,发现连接不上。然后改用fwknop的客户端fwknop -A tcp/22 -s 本机IP -D 服务器ip,提示输入密码,就是对称密码。再看ipt的日志,提示新增加规则,此时ssh就上去了。再看日志,已经删除了ipt的相应规则。因版本变化,原书中的-k参数貌似不能用了。如果想查看fwknop新开的规则可以使用fwknop --fw-list。

非对称的需要双方都声称密钥:
gpg --gen-key,一路默认。密钥生成后到处 gpg -a --export “serverkey” > serverkey.asc
已有的密钥可以通过gpg --list-keys查看,记得分清楚密钥的ID和文件名称,别弄混了。
双方交换密钥并导入gpg --import serverkey.asc。
修改密钥使用:gpg --default-key “serverkey” --sign-key “clientkey”
两遍配置完毕后把服务器的access.conf文件进行修改,需要写入gpg的密钥。
客户端访问的指令是:fwknop -A tcp/22 --gpg-recipient-key "fwknop_server_key" --gpg-signer-key "fwknop_client_key" -s 192.168.249.11 -U thanatos -D 192.168.249.10  \\老版本的指令不同

抗重放攻击:执行最后一次指令发个spa包,中间人tcpdump -i eth0 -l -nn -s 0 udp port 62201 -w spa.pcap,算是把SPA包给抓到了,然后看看包内容tcpdump -l -nn -X -r spa.pcap | head,可以看出来62201是个spa包。于是重放tcpreplay -i eth0 spa.pcap
查看服务器端log就发现早就发现重放了,一概不理会。

正常的客户端也可以通过

fwknop --spoof-src 222.222.222.222 -A tcp/22 --gpg-home-dir /root/.gnupg --spoof-user thanatos --gpg-recipient-key "fwknop_server_key" --gpg-signer-key "fwknop_client_key" -s 222.222.222.222 -D 192.168.249.10伪造一个地址,但是fwknop服务器还是能够找到正确的客户端并给添加规则。

把fwknop和ssh整合。下载ssh的spa补丁,并打上:
在ssh源码目录中path -p1 < openssh-4.3p2_SPA.path然后安装ssh,以后就可以直接ssh --gpg-recipient-key 123123 --gpg-signer-key 123123 -A tcp/22 -D 192.168.249.10” root@x.x.x.x了,不过这个指令没有测试。

通过tor发送的spa因为是tcp所以只能被迫在fwknop上打开fwknop_serv守护进程,这个守护进程只调用一次recv(),只收一个TPC包,尽可能的向UDP靠拢。

第十三章完
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-25 14:04:46 | 显示全部楼层
占楼占楼占楼7
回复 支持 反对

使用道具 举报

发表于 2010-6-25 14:50:19 | 显示全部楼层
也占8楼。加上精华~~~

谢谢兄弟,辛苦了~~

北南 呈上
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表