7.3 限制联机埠口 (port)

为什么我们的主机会响应网络上面的一些要求封包呢?例如我们设定了一部 WWW 主机后,当有来自 Internet 的 WWW 要求时,我们的主机就会予以回应,这是因为我们的主机有启用了 WWW 的监听埠口啊!所以,当我们启用了一个 daemon 时,就可能会造成主机的端口在进行监听的动作,此时该 daemon 就是已经对网络上面提供服务了!万一这个 daemon 程序有漏洞,因为他提供了 Internet 的服务,所以就容易被 Internet 上面的 cracker 所攻击了!所以说,仔细的检查自己系统上面的端口到底开了多少个,并且予以严格的管理,才能够降低被攻击的可能性啊!


7.3.1 什么是 port

快讲到烂掉了!当妳启动一个网络服务,这个服务会依据 TCP/IP 的相关通讯协议启动一个埠口在进行监听, 那就是 TCP/UDP 封包的 port (埠口) 了。我们从第二章也知道网络联机是双向的,服务器端得要启动一个监听的埠口, 客户端得要随机启动一个埠口来接收响应的数据才行。那么服务器端的服务是否需要启动在固定的埠口? 客户端的埠口是否又是固定的呢?我们将第二章中与 port 有关的资料给她汇整一下先:

  • 服务器端启动的监听埠口所对应的服务是固定的: 例如 WWW 服务开启在 port 80 ,FTP 服务开启在 port 21,email 传送开启在 port 25 等等,都是通讯协议上面的规范!

  • 客户端启动程序时,随机启动一个大于 1024以上的埠口: 客户端启动的 port 是随机产生的,主要是开启在大于 1024 以上的埠口。这个 port 也是由某些软件所产生的, 例如浏览器、Filezilla 这个 FTP 客户端程序等等。

  • 一部服务器可以同时提供多种服务: 所谓的『监听』是某个服务程序会一直常驻在内存当中,所以该程序启动的 port 就会一直存在。 只要服务器软件激活的埠口不同,那就不会造成冲突。当客户端连接到此服务器时,透过不同的埠口,就可以取得不同的服务数据啰。 所以,一部主机上面当然可以同时启动很多不同的服务啊!

  • 共 65536 个 port: 由第二章的 TCP/UDP 表头数据中,就知道 port 占用 16 个位,因此一般主机会有 65536 个 port,而这些 port 又分成两个部分,以 port 1024 作区隔:

    • 只有 root 才能启动的保留的 port: 在小于 1024 的埠口,都是需要以 root 的身份才能启动的,这些 port 主要是用于一些常见的通讯服务,在 Linux 系统下,常见的协议与 port 的对应是记录在 /etc/services 里面的。

    • 大于 1024 用于 client 端的 port: 在大于 1024 以上的 port 主要是作为 client 端的软件激活的 port 。

  • 是否需要三向交握: 建立可靠的联机服务需要使用到 TCP 协议,也就需要所谓的三向交握了,如果是非面向连接的服务,例如 DNS 与视讯系统, 那只要使用 UDP 协议即可。

  • 通讯协议可以启用在非正规的 port: 我们知道浏览器默认会连接到 WWW 主机的 port 80,那么你的 WWW 是否可以启动在非 80 的其他埠口? 当然可以啊!你可以透过 WWW 软件的设定功能将该软件使用的 port 启动在非正规的埠口, 只是如此一来,您的客户端要连接到你的主机时,就得要在浏览器的地方额外指定你所启用的非正规的埠口才行。 这个启动在非正规的端口功能,常常被用在一些所谓的地下网站啦!^_^。另外, 某些软件默认就启动在大于 1024 以上的端口,如 MySQL 数据库软件就启动在 3306。

  • 所谓的 port 的安全性: 事实上,没有所谓的 port 的安全性!因为『Port 的启用是由服务软件所造成的』, 也就是说,真正影响网络安全的并不是 port ,而是启动 port 的那个软件 (程序)! 或许你偶而会听到:『没有修补过漏洞的 bind 8.x 版,很容易被黑客所入侵,请尽快升级到 bind 9.x 以后版本』,所以啰,对安全真正有危害的是『某些不安全的服务』 而不是『开了哪些 port 』才是!因此,没有必要的服务就将他关闭吧! 尤其某些网络服务还会启动一些 port 哩!另外,那些已启动的软件也需要持续的保持更新喔!


7.3.2 埠口的观察: netstat, nmap

好了,我们现在知道这个 port 是什么鬼东西了,再来就是要来了解一下,我们的主机到底是开了多少的 port 呢?由于 port 的启动与服务有关,那么『服务』跟『 port 』对应的档案是哪一个?再提醒一次呦!是『 /etc/services 』啦!而常用来观察 port 的则有底下两个程序:

  • netstat:在本机上面以自己的程序监测自己的 port;
  • nmap:透过网络的侦测软件辅助,可侦测非本机上的其他网络主机,但有违法之虞。

见他的大头王!怎么使用 nmap 会违法?由于 nmap 的功能太强大了,所以很多 cracker 会直接以他来侦测别人的主机,这个时候就可能造成违法啦!只要你使用 nmap 的时候不要去侦测别人的计算机主机,那么就不会有问题啦!底下我们分别来说一说这两个宝贝吧!


  • netstat

在做为服务器的 Linux 系统中,开启的网络服务越少越好! 因为较少的服务可以较容易除错 (debug) 与了解安全漏洞,并可避免不必要的入侵管道! 所以,这个时候请了解一下您的系统当中有没有哪些服务被开启了呢? 要了解自己的系统当中的服务项目,最简便的方法就是使用 netstat 了!这个东西不但简单,而且功能也是很不错的。 这个指令的使用方法在 第五章常用网络功能指令介绍当中提过了, 底下我们仅提供如何使用这个工具的方法啰!

  • 列出在监听的网络服务:

    [root@www ~]# netstat -tunl
    ctive Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address    Foreign Address    State
    tcp        0      0 0.0.0.0:111      0.0.0.0:*          LISTEN
    tcp        0      0 0.0.0.0:22       0.0.0.0:*          LISTEN
    tcp        0      0 127.0.0.1:25     0.0.0.0:*          LISTEN
    ....(底下省略)....
    

    上面说明了我的主机至少有启动 port 111, 22, 25 等,而且观察各联机接口,可发现 25 为 TCP 埠口,但只针对 lo 内部循环测试网络提供服务,因特网是连不到该埠口的。至于 port 22 则有提供因特网的联机功能。

  • 列出已联机的网络联机状态:

    [root@www ~]# netstat -tun
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address       Foreign Address     State
    tcp        0     52 192.168.1.100:22    192.168.1.101:2162  ESTABLISHED
    

    从上面的数据来看,我的本地端服务器 (Local Address, 192.168.1.100) 目前仅有一条已建立的联机,那就是与 192.168.1.101 那部主机连接的联机,并且联机方线是由对方连接到我主机的 port 22 来取用我服务器的服务吶!

  • 删除已建立或在监听当中的联机:

    如果想要将已经建立,或者是正在监听当中的网络服务关闭的话,最简单的方法当然就是找出该联机的 PID, 然后将他 kill 掉即可啊!例如下面的范例:

    [root@www ~]# netstat -tunp
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address    Foreign Address     State       PID/P name
    tcp        0     52 192.168.1.100:22 192.168.1.101:2162  ESTABLISHED 1342/0
    

    如上面的范例,我们可以找出来该联机是由 sshd 这个程序来启用的,并且他的 PID 是 1342, 希望你不要心急的用 killall 这个指令,否则容易删错人 (因为你的主机里面可能会有多个 sshd 存在), 应该要使用 kill 这个指令才对喔!

    [root@www ~]# kill -9 1342
    

  • nmap

如果你要侦测的设备并没有可让你登入的操作系统时,那该怎么办?举例来说,你想要了解一下公司的网络打印机是否有开放某些协议时, 那该如何处理啊?现在你知道 netstat 可以用来查阅本机上面的许多监听中的通讯协议, 那例如网络打印机这样的非本机的设备,要如何查询啊?呵呵!用 nmap 就对了!

nmap (注1)的软件说明之名称为:『Network exploration tool and security / port scanner』,顾名思义, 这个东西是被系统管理员用来管理系统安全性查核的工具!他的具体描述当中也提到了, nmap 可以经由程序内部自行定义的几个 port 对应的指纹数据,来查出该 port 的服务为何,所以我们也可以藉此了解我们主机的 port 到底是干嘛用的!在 CentOS 里头是有提供 nmap 的, 如果你没有安装,那么就使用 yum 去安装他吧!

[root@www ~]# nmap [扫瞄类型] [扫瞄参数] [hosts 地址与范围]
选项与参数:
[扫瞄类型]:主要的扫瞄类型有底下几种:
    -sT:扫瞄 TCP 封包已建立的联机 connect() !
    -sS:扫瞄 TCP 封包带有 SYN 卷标的数据
    -sP:以 ping 的方式进行扫瞄
    -sU:以 UDP 的封包格式进行扫瞄
    -sO:以 IP 的协议 (protocol) 进行主机的扫瞄
[扫瞄参数]:主要的扫瞄参数有几种:
    -PT:使用 TCP 里头的 ping 的方式来进行扫瞄,可以获知目前有几部计算机存活(较常用)
    -PI:使用实际的 ping (带有 ICMP 封包的) 来进行扫瞄
    -p :这个是 port range ,例如 1024-, 80-1023, 30000-60000 等等的使用方式
[Hosts 地址与范围]:这个有趣多了,有几种类似的类型
    192.168.1.100  :直接写入 HOST IP 而已,仅检查一部;
    192.168.1.0/24 :为 C Class 的型态,
    192.168.*.*    +   :嘿嘿!则变为 B Class 的型态了!扫瞄的范围变广了!
    192.168.1.0-50,60-100,103,200 :这种是变形的主机范围啦!很好用吧!

# 范例一:使用预设参数扫瞄本机所启用的 port (只会扫瞄 TCP)
[root@www ~]# yum install nmap
[root@www ~]# nmap localhost
PORT    STATE SERVICE
22/tcp  open  ssh
25/tcp  open  smtp
111/tcp open  rpcbind
# 在预设的情况下,nmap 仅会扫瞄 TCP 的协议喔!

nmap 的用法很简单吶!就直接在指令后面接上 IP 或者是主机名即可。不过,在预设的情况下 nmap 仅会帮你分析 TCP 这个通讯协议而已,像上面这个例子的输出结果。但优点是顺道也将开启该埠口的服务也列出来了, 真是好! ^_^!那如果想要同时分析 TCP/UDP 这两个常见的通讯协议呢?可以这样做:

# 范例二:同时扫瞄本机的 TCP/UDP 埠口
[root@www ~]# nmap -sTU localhost
PORT    STATE SERVICE
22/tcp  open  ssh
25/tcp  open  smtp
111/tcp open  rpcbind
111/udp open  rpcbind  <==会多出 UDP 的通讯协议埠口!

嘿嘿!与前面的范例比较一下,你会发现这次多了几个 UDP 的埠口,这样分析好多了!然后, 如果你想要了解一下到底有几部主机活在你的网络当中时,则可以这样做:

# 范例三:透过 ICMP 封包的检测,分析区网内有几部主机是启动的
[root@www ~]# nmap -sP 192.168.1.0/24
Starting Nmap 5.21 ( http://nmap.org ) at 2011-07-20 17:05 CST
Nmap scan report for www.centos.vbird (192.168.1.100)
Host is up.
Nmap scan report for 192.168.1.101 <==这三行讲的是 192.168.101 的范例!
Host is up (0.00024s latency).
MAC Address: 00:1B:FC:58:9A:BB (Asustek Computer) 
Nmap scan report for 192.168.1.254
Host is up (0.00026s latency).
MAC Address: 00:0C:6E:85:D5:69 (Asustek Computer)
Nmap done: 256 IP addresses (3 hosts up) scanned in 3.81 seconds

看到否?鸟哥的环境当中有三部主机活着吶 (Host is up)!并且该 IP 所对应的 MAC 也会被记录下来, 很不错吧!如果你还想要将各个主机的启动的 port 作一番侦测的话,那就得要使用:

[root@www ~]# nmap 192.168.1.0/24

之后你就会看到一堆 port number 被输出到屏幕上啰~如果想要随时记录整个网段的主机是否不小心开放了某些服务, 嘿嘿!利用 nmap 配合数据流重导向 (>, >> 等) 来输出成为档案, 那随时可以掌握住您局域网络内每部主机的服务启动状况啊! ^_^

请特别留意,这个 nmap 的功能相当的强大,也是因为如此,所以很多刚在练习的黑客会使用这个软件来侦测别人的计算机。 这个时候请您特别留意,目前很多的人已经都有『特别的方式』来进行登录的工作!例如以 TCP_Wrappers (/etc/hosts.allow, /etc/hosts.deny) 的功能来记录曾经侦测过该 port 的 IP! 这个软件用来『侦测自己机器的安全性』是很不错的一个工具,但是如果用来侦测别人的主机, 可是会『吃上官司』的!特别留意!!


7.3.3 埠口与服务的启动/关闭及开机时状态设定

从第二章的数据我们就知道,其实 port 是由执行某些软件之后被软件激活的。所以要关闭某些 port 时,那就直接将某个程序给他关闭就是了!关闭的方法你当然可以使用 kill,不过这毕竟不是正统的解决之道,因为 kill 这个指令通常具有强制关闭某些程序的功能,但我们想要正常的关闭该程序啊! 所以,就利用系统给我们的 script 来关闭就好了啊。 在此同时,我们就得再来稍微复习一下,一般传统的服务有哪几种类型?


  • stand alone 与 super daemon

我们在基础学习篇内谈到,在一般正常的 Linux 系统环境下,服务的启动与管理主要有两种方式:

  • Stand alone 顾名思义,stand alone 就是直接执行该服务的执行档,让该执行文件直接加载到内存当中运作, 用这种方式来启动可以让该服务具有较快速响应的优点。一般来说,这种服务的启动 script 都会放置到 /etc/init.d/ 这个目录底下,所以你通常可以使用:『 /etc/init.d/sshd restart 』之类的方式来重新启动这种服务;

  • Super daemon 用一个超级服务作为总管,来统一管理某些特殊的服务。在 CentOS 6.x 里面使用的则是 xinetd 这个 super daemon 啊!这种方式启动的网络服务虽然在响应上速度会比较慢, 不过,可以透过 super daemon 额外提供一些控管,例如控制何时启动、何时可以进行联机、 那个 IP 可以连进来、是否允许同时联机等等。通常个别服务的配置文件放置在 /etc/xinetd.d/ 当中,但设定完毕后需要重新以『 /etc/init.d/xinetd restart 』重新来启动才行!

关于更详细的服务说明,请参考基础篇的认识服务一文, 鸟哥在这里不再赘述。好,那么如果我想要将我系统上面的 port 111 关掉的话, 那应该如何关闭呢?最简单的作法就是先找出那个 port 111 的启动程序喔!

[root@www ~]# netstat -tnlp | grep 111
tcp        0      0 0.0.0.0:111    0.0.0.0:*       LISTEN  990/rpcbind
tcp        0      0 :::111         :::*            LISTEN  990/rpcbind
# 原来用的是 rpcbind 这个服务程序!

[root@www ~]# which rpcbind
/sbin/rpcbind
# 找到档案后,再以 rpm 处理处理

[root@www ~]# rpm -qf /sbin/rpcbind
rpcbind-0.2.0-8.el6.x86_64
# 找到了!就是这个软件!所以将他关闭的方法可能就是:

[root@www ~]# rpm -qc rpcbind | grep init
/etc/rc.d/init.d/rpcbind
[root@www ~]# /etc/init.d/rpcbind stop

透过上面的这个分析的流程,你可以利用系统提供的很多方便的工具来达成某个服务的关闭! 为啥这么麻烦?不是利用 kill -9 990 就可以删掉该服务了吗? 是没错啦!不过,你知道该服务是做啥用的吗?你知道将他关闭之后,你的系统会出什么问题吗? 如果不知道的话,那么利用上面的流程不就可以找出该服务软件,再利用 rpm 查询功能, 不就能够知道该服务的作用了?所以说,这个方式还是对您会有帮助的啦! 底下请您试着将您 CentOS 或者是其他版本的 Linux 的 Telnet 打开试看看。

例题:我们知道系统的 Telnet 服务通常是以 super daemon 来控管的,请您启动您系统的 telnet 试看看。答:

  1. 要启动 telnet 首先必须要已经安装了 telnet 的服务器才行,所以请先以 rpm 查询看看是否有安装 telnet-server 呢? 『rpm -qa | grep telnet-server』如果没有安装的话,请利用原版光盘来安装,或者使用『yum install telnet-server』 安装一下先;
  2. 由于是 super daemon 控管,所以请编辑 /etc/xinetd.d/telnet 这个档案,将其中的『disable = yes』改成 『disable = no』之后以『/etc/init.d/xinetd restart』重新启动 super daemon 吧!
  3. 利用 netstat -tnlp 察看是否有启动 port 23 呢?

  • 预设启动的服务

刚刚上头的作法仅是『立即将该服务启动或关闭』喔!并不会影响到下次开机时,这个服务是否预设启动的情况。 如果你想要在开机的时候就启动或不启动某项服务时,那就得要了解一下基础学习篇里面谈到的开机流程管理的内容啦!在 Unix like 的系统当中我们都是透过 run level 来设定某些执行等级需要启动的服务,以 Red Hat 系统来说,这些 run level 启动的数据都是放置在 /etc/rc.d/rc[0-6].d/ 里面的,那如何管理该目录下的 script 呢?手动处理吗?会疯掉的吶!所以你必须要熟悉 chkconfigRed Hat 系统的 ntsysv 这几个指令才行!

Tips: 这几个指令不熟吗?这个时候鸟哥不得不说了:『有 man 堪用直需用,莫待无 man 空自猜』赶紧给他 man 下去啦!

例题:(1)如何查阅 rpcbind 这个程序一开机就执行? (2)如果开机就执行,如何将他改为开机时不要启动? (3)如何立即关闭这个 rpcbind 服务?答:

  1. 可以透过『 chkconfig --list | grep rpcbind 』与『 runlevel 』确认一下你的环境与 rpcbind 是否启动?
  2. 如果有启动,可透过『 chkconfig --level 35 rpcbind off 』来设定开机时不要启动;
  3. 可以透过『 /etc/init.d/rpcbind stop 』来立即关闭他!

聪明的你一定会问说:『鸟哥,你的意思是只要将系统所有的服务都关闭,那系统就会安全啰?』 当然....不是!因为『很多的系统服务是必须要存在的,否则系统将会出问题』 举例来说,那个保持系统可以具有工作排程的 crond 服务就一定要存在,而那个记录系统状况的 rsyslogd 也当然要存在~否则怎知道系统出了啥问题?所以啰,除非你知道每个服务的目的是啥,否则不要随便关闭该服务。 底下鸟哥列出几个常见的必须要存在的系统服务给大家参考参考先!这些服务请不要关闭啊!

服务名称 服务内容
acpid 新版的电源管理模块,通常建议开启,不过,某些笔记本电脑可能不支持此项服务,那就得关闭
atd 在管理单一预约命令执行的服务,应该要启动的
crond 在管理工作排程的重要服务,请务必要启动啊!
haldaemon 作系统硬件变更侦测的服务,与 USB 设备关系很大
iptables Linux 内建的防火墙软件,这个也可以启动啦!
network 这个重要了吧?要网络就要有他啊!
postfix 系统内部邮件传递服务,不要随便关闭他!
rsyslog 系统的登录文件记录,很重要的,务必启动啊!
sshd 这是系统默认会启动的,可以让你在远程以文字型态的终端机登入喔!
xinetd 就是那个 super daemon 嘛!所以也要启动啦!

上面列出的是主机需要的重点服务,请您不要关闭他!除非你知道作了之后会有什么后果。举例来说,你如果不需要管理电源, 那么将 acpid 关闭也没有关系啊!如果你不需要提供远程联机功能,那么 sshd 也可以关闭啊!那其他你不知道的服务怎办? 没关系,只要不是网络服务,你都可以保留他!如果是网络服务呢?那...鸟哥建议你不知道的服务就先关闭他! 以后我们谈到每个相关的服务时,再一个一个打开即可。底下我们就来做作看关闭网络服务这个部分!


7.3.4 安全性考虑-关闭网络服务端口

我们的 Linux distribution 很好心的帮使用者想到很多了,所以在一安装完毕之后, 系统会开启一堆有的没有的网络服务,例如那个 rpcbind 之类的咚咚,这些东西你或许知道或许不知道,不过他就是有开启~ 但我们的主机明明就是用来做为服务器的,所以这些本来预计要给 client 使用的服务其实有点『多此一举』的感觉~ 所以啦,请你将他关闭吧!底下我们举个简单的例子来处理,将你的网络服务关闭就好,其他在系统内部的服务,就暂时保留吧!

例题:找出目前系统上面正在运作中的服务,并且找到相对应的启动脚本 (在 /etc/init.d 内的档名之意)。答:要找出服务,就利用 netstat -tunlp 即可找到!以鸟哥从第一章安装的示范机为例,鸟哥目前启动的网络服务有底下这些:

[root@www ~]# netstat -tlunp
Active Internet connections (only servers)
Proto  Local Address        State       PID/Program name
tcp    0.0.0.0:22           LISTEN      1176/sshd
tcp    127.0.0.1:25         LISTEN      1252/master
tcp    0.0.0.0:37753        LISTEN      1008/rpc.statd
tcp    :::22                LISTEN      1176/sshd
tcp    :::23                LISTEN      1851/xinetd
tcp    ::1:25               LISTEN      1252/master
tcp    :::38149             LISTEN      1008/rpc.statd
tcp    0.0.0.0:111          LISTEN      1873/rpcbind
tcp  0 :::111               LISTEN      1873/rpcbind
udp  0 0.0.0.0:111                      1873/rpcbind
udp  0 0.0.0.0:776                      1873/rpcbind
udp  0 :::111                           1873/rpcbind
udp  0 :::776                           1873/rpcbind
udp    0.0.0.0:760                      1008/rpc.statd
udp    0.0.0.0:52525                    1008/rpc.statd
udp    :::52343                         1008/rpc.statd
# 上述的输出鸟哥有稍微简化一些喔,所以有些字段不见了。
# 这个重点只是要展现出最后一个字段而已啦!

看起来总共有 sshd, master, rpc.statd, xinetd, rpcbind 等这几个服务,对照前一小节的数据内容来看, master (port 25), sshd 不能关掉,那么其他的就予以关闭啊!透过前两个小节的介绍,使用 which 与 rpm 搜寻吧!举例来说, rpc.statd 的启动脚本在:『rpm -qc $(rpm -qf $(which rpc.statd) ) | grep init』这样找,结果是在『/etc/rc.d/init.d/nfslock』这里! 因此最终的结果如下:

rpc.statd /etc/rc.d/init.d/nfs
          /etc/rc.d/init.d/nfslock
          /etc/rc.d/init.d/rpcgssd
          /etc/rc.d/init.d/rpcidmapd
          /etc/rc.d/init.d/rpcsvcgssd
xinetd    /etc/rc.d/init.d/xinetd
rpcbind   /etc/rc.d/init.d/rpcbind

接下来就是将该服务关闭,并且设定为开机不启动吧!

[root@www ~]# vim bin/closedaemon.sh
for daemon in nfs nfslock rpcgssd rpcidmapd rpcsvcgssd xinetd rpcbind
do
    chkconfig $daemon off
    /etc/init.d/$daemon stop
done
[root@www ~]# sh bin/closedaemon.sh

做完上面的例子之后,你再次下达 netstat -tlunp 之后,会得到仅剩 port 25, 22 而已! 如此一来,绝大部分服务器用不到的服务就被你关闭,而且即使重新启动也不会被启动的啦! ^_^