ssh安全与IPTABLES操作
1、修改SSH监听端口
默认情况下,SSH监听连接端口22,攻击者使用端口扫描软件就可以看到主机是否运行有SSH服务,将SSH端口修改为大于1024的端口是一个明智的选择,因为大多数端口扫描软件(包括nmap)默认情况都不扫描高位端口。
打开/etc/ssh/sshd_config文件并查找下面这样的行:
Port 22
修改端口号并重新启动SSH服务:
/etc/init.d/ssh restart
2、仅允许SSH协议版本2
有两个SSH协议版本,仅使用SSH协议版本2会更安全,SSH协议版本1有安全问题,包括中间人攻击(man-in-the-middle)和注入(insertion)攻击。编辑/etc/ssh/sshd_config文件并查找下面这样的行:
Protocol 2,1
修改为
Protocol 2
3、仅允许特定的用户通过SSH登陆
你不一个允许root用户通过SSH登陆,因为这是一个巨大的不必要的安全风险,如果一个攻击者获得root权限登陆到你的系统,相对他获得一个普通用户权限能造成更大的破坏,配置SSH服务器不允许root用户通过SSH登陆,查找下面这样的行:
PermitRootLogin yes
将yes修改为no,然后重新启动服务。现在,如果你想使用特权用户,你可以先以其他用户登陆,然后再转换到root。
创建一个没有实际权限的虚拟用户是一个明智的选择,用这个用户登陆SSH,即使这个用户遭到破解也不会引起什么破坏,当创建这个用户时,确保它属于wheel组,因为那样你才能切换到特权用户。
如果你想让一列用户都能通过SSH登陆,你可以在sshd_config文件中指定它们,例如:我想让用户anze、dasa、kimy能通过SSH登陆,在sshd_config文件的末尾我添加下面这样一行:
AllowUsers anze dasa kimy
4、创建一个自定义SSH banner
如果你想让任何连接到你SSH服务的用户看到一条特殊的消息,你可以创建一个自定义SSH banner,只需要创建一个文本文件(我的是/etc/ssh-banner.txt),然后输入你想的任何文本消息,如:
*This is a private SSH service. You are not supposed to be here.*
*Please leave immediately. *
编辑好后,保存这个文件,在sshd_config中查找下面这样一行:
#Banner /etc/issue.net
取消掉注释【将#去掉】,然后将路径修改为你自定义的SSH banner文本文件。
5、使用DSA公钥认证
代替使用用户名和密码对SSH进行认证,你可以使用DSA公钥进行认证,注意你既可以使用登陆名,也可以使用DSA公钥进行认证,使用DSA公钥认证可以预防你的系统遭受字典攻击,因为你不需要用登陆名和密码登陆SSH服务,而是需要一对DSA密钥,一个公钥和一个私钥,在你本地机器上保存私钥,将公钥放在服务器上。当你发起一个SSH登陆会话时,服务器检查密钥,如果它们匹配的话,你就可以直接进入shell,如果它们不匹配,你的连接将被自动断开。
在本例中的私人计算机叫‘工作站1’,服务器叫‘服务器1’。在两个机器上我有相同的home目录,如果服务器和客户端上的home目录不同将不能工作,实现,你需要在你的私人计算机上创建一对密钥,命令:~$ ssh-keygen -t dsa,它将要求你为私钥输入一个密语,但是你可以保留为空,因为这不是一个推荐的做法。密钥对创建好了:你的私钥在~/.ssh/id_dsa,你的公钥在.ssh/id_dsa.pub。
接下来,拷贝~/.ssh/id_dsa.pub中的内容到‘服务器1’的~/.ssh/authorized_keys文件中,~/.ssh/id_dsa.pub的内容看起来象下面这样:
~$ cat .ssh/id_dsa.pub
ssh-dss AAAAB3NzaC1kc3MAAACBAM7K7vkK5C90RsvOhiHDUROvYbNgr7YEqtrdfFCUVwMWc
JYDusNGAIC0oZkBWLnmDu+y6ZOjNPOTtPnpEX0kRoH79maX8NZbBD4aUV91lbG7z604ZTdr
LZVSFhCI/Fm4yROHGe0FO7FV4lGCUIlqa55+QP9Vvco7qyBdIpDuNV0LAAAAFQC/9ILjqII7n
M7aKxIBPDrQwKNyPQAAAIEAq+OJC8+OYIOeXcW8qcB6LDIBXJV0UT0rrUtFVo1BN39cAWz5pu
Fe7eplmr6t7Ljl7JdkfEA5De0k3WDs
9/rD1tJ6UfqSRc2qPzbn0p0j89LPIjdMMSISQqaKO4m2fO2VJcgCWvsghIoD0AMRC7ngIe6bta
NIhBbqri10RGL5gh4AAACAJj1/rV7iktOYuVyqV3BAz3JHoaf+H/dUDtX+wuTuJpl+tfDf61rb
WOqrARuHFRF0Tu/Rx4oOZzadLQovafqrDnU/No0Zge+WVXdd4ol1YmUlRkqp8vc20ws5mLVP
34fST1amc0YNeBp28EQi0xPEFUD0IXzZtXtHVLziA1/NuzY= [email protected]
如果文件~/.ssh/authorized_keys已经存在,请将上面的内容附加在该文件的后面。剩下的只是给该文件设置正确的权限了:
~$ chmod 600 ~/.ssh/authorized_keys
现在,配置sshd_config文件使用DSA密钥认证,确保你将下面三行前的注释去掉了:
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
重新启动服务,如果你的配置没有错误,现在你就可以SSH到你的服务器,而且无需任何交互动作(如输入用户名和密码)就直接进入你的home目录了。
如果你只想使用DSA认证登陆,确保你在sshd_config中取消掉注释并修改PasswordAuthentication这一行,将yes改为no:
PasswordAuthentication no
任何在服务器上没有公钥的人试图连接到你的SSH服务,它就被拒绝,给它显示如下一个拒绝提示信息:
Permission denied (publickey).
6、使用TCP wrappers仅允许指定的主机连接
如果你想在你的网络上只允许特定的主机才能连接到你的SSH服务,但又不想使用或弄乱你的iptables配置,那这个方法非常有用,你可以使用TCP wrappers。在这个例子中对sshd进行TCP包裹,我将创建一条规则允许本地子网192.168.1.0/24和远程172.16.20.13的自己连接到我的SSH服务。
默认情况下,TCP wrappers首先在/etc/hosts.deny中查找看主机是否允许访问该服务,接下来,TCP wrappers查找/etc/hosts.allow看是否有规则允许该主机服务指定的服务,我将在/etc/hosts.deny中创建一个规则,如下:
sshd: ALL
这意味着默认情况下所有主机被拒绝访问SSH服务,这是应该的,否则所有主机都能访问SSH服务,因为TCP wrappers首先在hosts.deny中查找,如果这里没有关于阻止SSH服务的规则,任何主机都可以连接。
接下来,在/etc/hosts.allow中创建一个规则允许指定的主机使用SSH服务:
sshd: 192.168.1 172.16.20.13
现在,只有来自192.168.1.0/24和172.16.20.13的主机能够访问SSH服务了,其他主机在连接时还没有到登陆提示符时就被断开了,并收到错误提示,如下:
ssh_exchange_identification: Connection closed by remote host
7、使用iptables允许特定的主机连接
作为TCP wrappers的一个代替品,你可以使用iptables来限制SSH访问(但可以同时使用这个两个的),这里有一个简单的例子,指出了如何允许一个特定的主机连接到你的SSH服务:
~# iptables -A INPUT -p tcp -m state --state NEW --source 172.16.20.13 --dport 22 -j ACCEPT
并确保没有其他的主机可以访问SSH服务:
~# iptables -A INPUT -p tcp --dport 22 -j DROP
保存你的新规则,你的任务就完成了,规则是立即生效的
8、SSH时间锁定技巧
你可以使用不同的iptables参数来限制到SSH服务的连接,让其在一个特定的时间范围内可以连接,其他时间不能连接。你可以在下面的任何例子中使用/second、/minute、/hour或/day开关。
第一个例子,如果一个用户输入了错误的密码,锁定一分钟内不允许在访问SSH服务,这样每个用户在一分钟内只能尝试一次登陆:
~# iptables -A INPUT -p tcp -m state --syn --state NEW --dport 22 -m limit --limit 1/minute --limit-burst 1 -j ACCEPT
~# iptables -A INPUT -p tcp -m state --syn --state NEW --dport 22 -j DROP
第二个例子,设置iptables只允许主机172.16.20.13连接到SSH服务,在尝试三次失败登陆后,iptables允许该主机每分钟尝试一次登陆:
~# iptables -A INPUT -p tcp -s 172.16.20.13 -m state --syn --state NEW --dport 22 -m limit --limit 1/minute --limit-burst 1 -j ACCEPT
~# iptables -A INPUT -p tcp -s 172.16.20.13 -m state --syn --state NEW --dport 22 -j DROP
IPTABLES设置实例
能让客户端上网的方法
方法一、把FORWARD的默认策略设置为DROP,然后一个一个服务开放,只能开放我们知道端口(用工具抓包,然后分析出IP地址和端口)的服务或者软件,这种情况会造成迅雷等软件无法使用(因为不知道迅雷下载时候用什么端口)
1.能ping iptables -t filter -A FORWARD -p icmp -j ACCEPT
2.能看网页 内网客户机出去的目标端口是80,53都放行 iptables -t filter -A FORWARD -p tcp -i eth1 --dport 80 -s 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth1 --dport 53 -s 172.20.80.0/24 -j ACCEPT iptables -t filter -A FORWARD -p udp -i eth1 --dport 53 -s 172.20.80.0/24 -j ACCEPT 或者 两者写其中一个即可 iptables -t filter -A FORWARD -p tcp --dport 80 -s 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 53 -s 172.20.80.0/24 -j ACCEPT iptables -t filter -A FORWARD -p udp --dport 53 -s 172.20.80.0/24 -j ACCEPT
解析后回来的源端口是80,53的都给与放行 iptables -t filter -A FORWARD -p tcp -i eth0 --sport 80 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth0 --sport 53 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 --sport 53 -d 172.20.80.0/24 -j ACCEPT
或者,两者写其中一个即可
iptables -t filter -A FORWARD -p tcp --sport 80 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p udp --sport 53 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --sport 53 -d 172.20.80.0/24 -j ACCEPT
3.能收发邮件 iptables -t filter -A FORWARD -p tcp --dport 25 -s 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --sport 25 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --sport 110 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 110 -s 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --sport 143 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 143 -s 172.20.80.0/24 -j ACCEPT
有其他端口的类似设置就可以了,一出一进配合。
4.上QQ QQ登录时可以使用2种情况,udp 8000 /tcp 80、443,会自动检测那个端口开放着,那个开放,就用那个端口登录 UDP 8000
iptables -t filter -A FORWARD -p udp --dport 8000 -s 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p udp --sport 8000 -d 172.20.80.0/24 -j ACCEPT
tcp 80(跟网页端口一样80,所以只要能看网页,那就能上QQ)
iptables -t filter -A FORWARD -p tcp --sport 80 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 80 -s 172.20.80.0/24 -j ACCEPT
tcp 443
iptables -t filter -A FORWARD -p tcp --sport 443 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 443 -s 172.20.80.0/24 -j ACCEPT
更严格的措施,就是找出QQ登录服务器的地址,然后设置:
iptables -t filter -A FORWARD -p tcp --dport 443 -s 172.20.80.0/24 -d 119.147.45.43 -j ACCEP
T iptables -t filter -A FORWARD -p tcp --sport 443 -s 119.147.45.43 -d 172.20.80.0/24 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --dport 80 -s 172.20.80.0/24 -d 112.95.240.16 -j ACCEPT
iptables -t filter -A FORWARD -p tcp --sport 80 -s 112.95.240.16 -d 172.20.80.0/24 -j ACCEPT
这种情况会造成比较多的软件无法使用,只有一个一个找出软件的IP地址和端口,才能使用,不建议这么设置
方法二、也是把FORWARD链的默认策略设置为DROP,然后手工添加要上网的IP地址(当然也可以用脚本批量添加),这样没有进行设置的客户端就无法上网,这种情况可以使用迅雷下载,还可以限制迅雷的速度,推荐使用这种方法
做以上设置是很严格了,但是好多应用不能用,而且迅雷这种软件根本就不知道用什么端口,连接那个IP地址,而且我们有事又需要用迅雷下载,这时我们就可以限制迅雷的下载速度,按照以下命令来:
a.让所有出去都可以出去
[[email protected] ~]# iptables -t nat -A POSTROUTING -s 172.20.80.0/24 -j SNAT --to 192.168.18.110
[[email protected] ~]# iptables -t filter -A FORWARD -i eth1 -s 172.20.80.0/24 -j ACCEPT
b.进来的要进行限速,对单个主机进行限速(要在网关的外网卡限制下载的速度,而在内网卡上限制上传的速度)
[[email protected] ~]# iptables -t filter -A FORWARD -i eth0 -d 172.20.80.2 -m limit --limit 10/s --limit-burst 10 -j ACCEPT
按照这个命令,这个主机最大也就14.6KB/S,根据实际情况对速度进行调整 -m limit --limit 10/s --limit-burst 10 该选项就是对主机进行限速 --limit 10/s:10/s是每秒发个10个包,又因网卡的MTU值为1500B,换算成KB,1500/1024=1.46KB,也就是每个包大小理想情况下是1.46KB,每秒10个包,那就是每秒1.46*10=14.6KB/S --limit-burst 10 :最大峰值也是10个包
c.做端口映射,有时间需要把内网的服务器发布到外网,让外网的用户也能访问,这时就需要端口映射。 访问网关的8080端口,就是相当于访问,内网172.20.80.2的80端口 [[email protected] ~]# iptables -t nat -A PREROUTING -p tcp -d 192.168.18.110 --dport 8080 -j DNAT --to 172.20.80.2:80
访问网关的3389端口,就相当于访问内网172.20.80.2的3389端口,这样就把3389端口映射出去了
[[email protected] ~]# iptables -t nat -A PREROUTING -p tcp -d 192.168.18.110 --dport 3389 -j DNAT --to 172.20.80.2:3389 做端口映射时,POSTROUTING链其实可以不做SNAT,iptables就能把进来的包交给内网机器,而内网机器也将数据回复到外网的机器,原因是:iptables是一种状态型的防火墙,不用我们手动将设置数据包的转发方向,它也能很好的转发我们的数据包。 查看nat表和filter表
[[email protected] ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 192.168.18.110 tcp dpt:8080 to:172.20.80.2:80
DNAT tcp -- 0.0.0.0/0 192.168.18.110 tcp dpt:3389 to:172.20.80.2:3389
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 172.20.80.0/24 0.0.0.0/0 to:192.168.18.110
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[[email protected] ~]# iptables -t filter -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- 172.20.80.0/24 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 172.20.80.0/24
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain RH-Firewall-1-INPUT (0 references)
target prot opt source destination 注意:这时候,就算filter中的INPUT和OUTPUT链默认策略是DROP,那也不会影响端口映射的,因为INPUT链和OUTPUT链只会对进入自己和自己出去的做限制,这时候是转发,所以不会影响。
d.发布内网的FTP服务器到外网去 先看FTP的工作模式:主动模式和被动模式 主动模式(Active):客户端以一个大于1024端口的随机端口(假设n端口),向服务器的21端口发出请求,服务器用21端口进行回应,然后服务器会以20端口,来主动去连接客户端的(n+1)端口,然后就开始传输数据.只有这种模式下才会用到20端口。
现在通过iptables 来发布FTP,先看主动模式: [[email protected] ~]# iptables -t nat -A PREROUTING -p tcp -d 192.168.18.110 --dport 21 -j DNAT --to 172.20.80.2:21
[[email protected] ~]# iptables -t nat -A PREROUTING -p tcp -d 192.168.18.110 --dport 20 -j DNAT --to 172.20.80.2:20 这时客户端如果设置为被动模式的话,是连接不到服务器
被动模式(Passive) 客户端以一个大于1024端口的随机端口(假设n端口),向服务器的21端口发出请求,服务器用21端口进行回应(这里面包含一个随机端口m,用于和客户端进行数据传输),然后客户端以n+1端口,连接服务器的m端口,最后传输数据。
以被动模式发布FTP,因为被动模式服务器端口是用随机端口和客户端进行数据传输,所以我们就不知道该发布什么端口出去,这时就需要借助2个模块来实现。
ip_nat_ftp和ip_conntrack_ftp这2个模块,加载到内核当中去,就可以实现FTP的被动模式的发布。
[[email protected] ~]# modprobe ip_nat_ftp
[[email protected] ~]# modprobe ip_conntrack_ftp
[[email protected] ~]# lsmod | grep ftp
2:ip_nat_ftp 7361 0
3:ip_conntrack_ftp 11569 1 ip_nat_ftp
14:ip_nat 20973 2 ip_nat_ftp,iptable_nat
15:ip_conntrack 53281 5 ip_nat_ftp,ip_conntrack_ftp,ip_conntrack_netbios_ns,iptable_nat,ip_nat 只需要发布21端口出去就可以了。
[[email protected] ~]# iptables -t nat -A PREROUTING -p tcp -d 192.168.18.110 --dport 21 -j DNAT --to 172.20.80.2:21
这样客户端就可以以被动模式(FTP客户端可以设置被动模式和主动模式)来连接到服务器,这时如果用主动模式连接服务器,是连接不到的。
所以FTP工作于什么模式,完全在于FTP客户端的设置,而不在于服务器端,大多数情况下服务器端是不开放20端口,所以我们只能用被动模式去连接处于内网中的FTP服务器
方法三、把FORWARD链默认设置为ACCEPT,然后来限制某些服务的运行,这种情况下,无法限制迅雷的速度,因为一旦FORWARD链设置为ACCEPT的话,其他策略设置都不起作用,不推荐这种方法,还有如果上网行为严格的话,那么要找到那么软件的使用的端口及IP地址很是麻烦。
限制QQ登录,首先要找到QQ登录都使用那些地址 tcpdump -i eth1 host 172.20.80.2 -s 0 -w qq.pcap 使用这个命令可以抓包,就可以知道某个软件使用什么端口,IP地址信息,然后把qq.pcap下载下来,用wireshark来分析 (点 Statistics-Conversation-IPv4),就可以看到QQ使用了多个地址,默认使用了UDP 8000 端口,把这些地址记下,使用iptables 来做限制 iptables -t filter -A FORWARD -p udp -s 172.20.80.0/24 -d 112.95.240.16 --dport 8000 -j DROP
iptables -t filter -A FORWARD -p udp -s 172.20.80.0/24 -d 112.95.240.16 -m multiport --dport 8000,80,443 -j DROP
多端口要这么设置 然后把这些地址和这些端口,封掉,但是webQQ无法封,因为使用80端口,以此类推找到其他不能使用的软件的端口IP地址,禁止掉。