欢迎各位兄弟 发布技术文章
这里的技术是共享的
stack 栈
tcp wrapper 工作在tcp层,对tcp的访问请求进行控制
可以理解成 tcpd 服务,但是它本身不是一个服务,它是一个库文件
tcpd 是编译进应用程序中的
库文件是 libwrap.so
一旦某个应用程序在编的时候链接到 tcpd 这个库上,
外面用户访问这个应用程序的时候,
tcpd是工作在用户请求和服务所监听的套接字之间的一种检查过滤机制,这种过滤机制可以拦载对某个特定服务的访问请求,
根据定义的规则,可以决定是否允许访问的这么一种机制
tcpd 是一个库,本身是工作在内核当中的,glibc库
开发者在开发应用程序的时候,提供一个钩子来调用 tcpd,才受到tcpd的访问控制
看看 sshd 程序所依赖的库
ldd 命令 查看某个命令所依赖的库
[root@mail xinetd.d]# man ldd
ldd - print shared library dependencies
[root@mail xinetd.d]# ldd `which sshd`
# 可以看到 libwrap,说明 sshd 是链接到 tcp wrapper 上面了,说明 sshd 将接受 tcp wrapper 的访问控制
# 下面列出的库,叫做动态链接库,程序需要时是动态加载进来的,通常以 so 结尾
# 要移植 sshd 这个程序的时候,下面的动态库也要移植,才能正常工作
# 我们可以在编译的时候,将这些库文件直接编译进应用程序里面去,所以此时程序体积会变大
linux-gate.so.1 => (0x00d96000)
libwrap.so.0 => /lib/libwrap.so.0 (0x007d4000)
libpam.so.0 => /lib/libpam.so.0 (0x00498000)
libdl.so.2 => /lib/libdl.so.2 (0x00275000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00cbb000)
libaudit.so.0 => /lib/libaudit.so.0 (0x00836000)
libfipscheck.so.1 => /usr/lib/libfipscheck.so.1 (0x004e8000)
libresolv.so.2 => /lib/libresolv.so.2 (0x00737000)
libcrypto.so.6 => /lib/libcrypto.so.6 (0x0027a000)
libutil.so.1 => /lib/libutil.so.1 (0x004bb000)
libz.so.1 => /lib/libz.so.1 (0x00e9f000)
libnsl.so.1 => /lib/libnsl.so.1 (0x0081c000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x0079d000)
libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x00147000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x001ad000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x00be9000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x00c21000)
libnss3.so => /usr/lib/libnss3.so (0x004ea000)
libc.so.6 => /lib/libc.so.6 (0x008b7000)
/lib/ld-linux.so.2 (0x0075a000)
libsepol.so.1 => /lib/libsepol.so.1 (0x003bb000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x004bf000)
libkeyutils.so.1 => /lib/libkeyutils.so.1 (0x00175000)
libnssutil3.so => /usr/lib/libnssutil3.so (0x00178000)
libplc4.so => /usr/lib/libplc4.so (0x0019b000)
libplds4.so => /usr/lib/libplds4.so (0x00262000)
libnspr4.so => /usr/lib/libnspr4.so (0x00c3c000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00244000)
librt.so.1 => /lib/librt.so.1 (0x0019f000)
[root@mail xinetd.d]#
[root@mail xinetd.d]# ldd `which xinetd` # 可以看到 libwrap
linux-gate.so.1 => (0x00915000)
libselinux.so.1 => /lib/libselinux.so.1 (0x0018c000)
libwrap.so.0 => /lib/libwrap.so.0 (0x009d4000)
libnsl.so.1 => /lib/libnsl.so.1 (0x0069e000)
libm.so.6 => /lib/libm.so.6 (0x005e6000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x00822000)
libc.so.6 => /lib/libc.so.6 (0x001a4000)
libdl.so.2 => /lib/libdl.so.2 (0x0036a000)
libsepol.so.1 => /lib/libsepol.so.1 (0x00bbf000)
/lib/ld-linux.so.2 (0x0075a000)
(马哥那边没看到 libwrap)
(马哥那边没装 xinetd)
[root@mail xinetd.d]#
[root@mail xinetd.d]# ldd `which httpd` # 没有看到 libwrap
linux-gate.so.1 => (0x003e3000)
libpcre.so.0 => /lib/libpcre.so.0 (0x009a8000)
libaprutil-1.so.0 => /usr/local/apr-util/lib/libaprutil-1.so.0 (0x00bf8000)
libexpat.so.0 => /lib/libexpat.so.0 (0x00c4f000)
libapr-1.so.0 => /usr/local/apr/lib/libapr-1.so.0 (0x00b32000)
libuuid.so.1 => /lib/libuuid.so.1 (0x001aa000)
librt.so.1 => /lib/librt.so.1 (0x0093b000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x0321a000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0091f000)
libdl.so.2 => /lib/libdl.so.2 (0x00903000)
libc.so.6 => /lib/libc.so.6 (0x00779000)
/lib/ld-linux.so.2 (0x0075a000)
[root@mail xinetd.d]#
[root@mail ~]# ldd `which portmap` #不包含 libwrap ,但事实上 portmap接受 libwrap控制的,因为libwrap是静态的,已经编译进portmap里面去了,不再需要使用动态链接的方式了
linux-gate.so.1 => (0x0053b000)
libnsl.so.1 => /lib/libnsl.so.1 (0x0060e000)
libc.so.6 => /lib/libc.so.6 (0x001bb000)
/lib/ld-linux.so.2 (0x0075a000)
[root@mail ~]#
[root@mail ~]# strings `which portmap` | grep hosts #看到 /etc/hosts.allow /etc/hosts.deny 说明portmap已将tcp wrapper 编译成本地应用程序,并接受tcp wrapper 的访问控制了
hosts_access_verbose
hosts_allow_table
hosts_deny_table
/etc/hosts.allow #对于tcp wrapper至关重要
/etc/hosts.deny #对于tcp wrapper至关重要
[root@mail ~]#
tcp wrapper
允许访问的列表,白名单 /etc/hosts.allow
拒绝访问的列表,黑名单 /etc/hosts.deny
telnet-server 安装时 依赖于 xinetd ,所以安装telnet-server,会顺便安装xinetd
[root@mail ~]# yum install telnet-server
马哥这边 现在可以看到 xinet 动态依赖库 libwrap 了
请求多时,尽量用独立守护进程
请求少时,尽量用瞬时守护进程
有些服务可以根据需要定义成独立或非独立, (telnet-server默认接受 xinet 管理,sshd可以接受 xinet 管理)
有些服务则只能工作在独立模式下(比如 apache 的 httpd,它不接受xinet管理 )
如果超级守护进程接受tcp wrapper 控制,那么超级守护进程管理的每一个服务都接受tcp wrapper 控制
/etc/hosts.allow
/etc/hosts.deny
这两个文件的语法格式
[root@mail ~]# which sshd #查可执行文件
/usr/sbin/sshd
[root@mail ~]#
[root@mail ~]# rpm -ql telnet-server
/etc/xinetd.d/telnet
/usr/sbin/in.telnetd #这个才是可执行文件
/usr/share/man/man5/issue.net.5.gz
/usr/share/man/man8/in.telnetd.8.gz
/usr/share/man/man8/telnetd.8.gz
[root@mail ~]#
daemon_list 是服务的可执行程序的二进制文件的名字
192.168.0. 表示网段
多个 daemon_list 用逗号隔开
ALL 表示本机上所有接受tcp wrapper 访问控制的服务,是一个宏变量(宏常量)?
daemon@host 这个host 指的是服务器端的其中一个ip地址(假如这个服务器有多个ip地址)
client_list
单ip
网络地址,一定不能写成位数格式 如 1.0.0.0/8
可以写成完整长格式 如 1.0.0.0/255.0.0.0
可以写成 172.16. 的格式,最后一个点不能少
主机名
可以 fqdn
可以 写成域名 如 .a.org 前面点不能少
宏 macro
ALL 表示所有客户端
LOCAL(本地来宾,跟本地网卡在同一网段内的主机),KNOWN(fqdn可以被正常解析的),UNKNOWN(fqdn无法被正常解析的),PARANOID(主机名正向解析和反向解析不匹配)
EXCEPT 除了,不包含
tcp wrapper
sshd 仅允许172.16.0.0/16 网段访问
方法:
/etc/hosts.allow
sshd: 172.16.
/etc/hosts.deny
sshd: ALL
telnet服务不允许172.16.0.0/16访问,但允许172.16.100.200访问
其它客户端不做控制
方法一:
1, /etc/hosts.allow
in.telnetd: 172.116.100.200
2. /etc/hosts.deny
in.telnetd: 172.16.
方法二:
/etc/hosts.deny
in.telnetd: 172.16. EXCEPT 172.16.100.200
方法在:
1. /etc/hosts.allow
in.telnetd: ALL EXPECT 172.16. EXCEPT 172.16.100.200
2. /ect/hosts.deny
in.telnetd: ALL 或者 ( 172.16. )
[root@mail ~]# service xinetd start
启动 xinetd:
[root@mail ~]#
确保iptables 不受影响
[root@mail ~]# iptables -L -n -v
Chain INPUT (policy ACCEPT 525K packets, 74M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 31115 packets, 5101K bytes)
pkts bytes target prot opt in out source destination
Chain RH-Firewall-1-INPUT (0 references)
pkts bytes target prot opt in out source destination
[root@mail ~]#
[root@mail ~]# ifconfig # 本地地址 192.168.1.75
eth0 Link encap:Ethernet HWaddr 00:0C:29:EC:30:EF
inet addr:192.168.1.75 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feec:30ef/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1463066 errors:6 dropped:1 overruns:0 frame:0
TX packets:29865 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:172969582 (164.9 MiB) TX bytes:5078866 (4.8 MiB)
Interrupt:67 Base address:0x2000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4671 errors:0 dropped:0 overruns:0 frame:0
TX packets:4671 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:559266 (546.1 KiB) TX bytes:559266 (546.1 KiB)
[root@mail ~]#
仅允许 192.168.1.0/24 的网段的电脑访问
[root@mail ~]# vim /etc/hosts.allow #允许192.168.1.0/24 的网段的电脑访问
#
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: 192.168.1.
[root@mail ~]# vim /etc/hosts.deny #拒绝所有主机
#
# hosts.deny This file describes the names of the hosts which are
# *not* allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: ALL
在 windows主机上 > telnet 192.168.1.75
[root@mail ~]# netstat -tnlp # 23号端口未启动
启动 telnet 服务 (它是瞬时服务) 瞬时服务没有等级的概念
[root@mail ~]# chkconfig telnet on
[root@mail ~]# service xinetd restart
停止 xinetd: [确定]
启动 xinetd: [确定]
[root@mail ~]#
[root@mail ~]# chkconfig --list
[root@mail ~]# netstat -tnlp # 23号端口开了
在 windows 上 ,可以连上了
在linux 上增加个用户
[root@mail ~]# passwd fedora
Changing password for user fedora.
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully.
[root@mail ~]#
在 windows 上输入用户名和密码 就可以登录 telnet 了
在 windows 用 telnet 连上linux 后,数据是不加密的,速度应该会快点,会不安全
仅允许 192.168.1.0/24 的网段的电脑访问,除了 192.168.1.251
[root@mail ~]# vim /etc/hosts.allow
#
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: 192.168.1. EXCEPT 192.168.1.251
[root@mail ~]# vim /etc/hosts.deny # /etc/hosts.deny 没有变化
#
# hosts.deny This file describes the names of the hosts which are
# *not* allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: ALL
~
修改后是实时的起作用,应该此时 windows 就不能访问了
直接跳到如下图的样子了
看看 options 选项
其中一种典型用法是在 allow中deny,在 deny中allow
下面就是常用的选项
spawn 可以在接收或拒绝访问后,产生日志的
:spawn echo "
:ALLO
:DENY
:in.telnetd
ALL
172.16.
172.16.100.100
假设已经定义了如下 仅允许172.16. 的网段访问,其它的都不允许访问
/etc/hosts.allow
in.telnetd: 172.16.
/etc/hosts.deny
in.telnetd:ALL
我们准备 in.telnetd 不允许 172.16. 的网段访问,其它的都可以访问
/etc/hosts.allow
in.telnetd: 172.16. :DENY # 在 allow中deny ,这个deny 就是一个options ,以 options的方式在工作
/etc/hosts.deny #内容为空
[root@mail ~]# vim /etc/hosts.allow
#
# hosts.deny This file describes the names of the hosts which are
# *not* allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: 192.168.1. :DENY
[root@mail ~]# vim /etc/hosts.deny # 把内容清空吧
应该此时 windows 就不能访问了
直接跳到如下图的样子了
[root@mail ~]# vim /etc/hosts.allow
#
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: 192.168.1. :spawn echo "somebody entered `date`" >> /var/log/tcpwrapper.log
[root@mail ~]# vim /etc/hosts.deny # 把内容清空吧
在windows 上登录一下
此时可以看到日志了
[root@mail ~]# tail /var/log/tcpwrapper.log
somebody entered Sun Aug 23 18:28:15 CST 2020
[root@mail ~]#
tcp wrapper macro: 有自己内部控制的变量(常量)(宏)
%c: client information (通常格式 user@host) 客户端用户
%s: service info (通常格式server@host,哪个ip上(多个ip的服务器中的某一个ip)的哪个服务) 服务端用户
%h: client hostname 客户端主机名
%p: server PID 明确说明访问的是哪个服务
这些宏可以通过 #man hosts.allow 来获取? 不对
应该是 # man 5 hosts_access 来获取 ,不止上面的四个,有很多的宏
例如
spawn echo "`date`, login attempt from %c to %s" >> /var/log/tcpwrapper.log #最好不要用冒号,冒号有特殊意义,可能会有问题
允许 192.168.1. 网段 并记入日志
[root@mail ~]# vim /etc/hosts.allow
#
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: 192.168.1. :spawn echo "`date`, login attempt from %c to %s." >> /var/log/tcpwrapper.log
拒绝其它所有 并记入日志
[root@mail ~]# vim /etc/hosts.deny
#
# hosts.deny This file describes the names of the hosts which are
# *not* allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: ALL :spawn echo "`date`, login attempt from %h " >> /var/log/tcpwrapper.log # 拒绝了没办法记录 %s 服务器了
在windows 上登录一下
看日志
[root@mail ~]# tail /var/log/tcpwrapper.log
somebody entered Sun Aug 23 18:28:15 CST 2020
somebody entered Sun Aug 23 18:28:53 CST 2020
Sun Aug 23 18:55:56 CST 2020, login attempt from 192.168.1.251 to in.telnetd@192.168.1.75.
[root@mail ~]#
做失败的尝试 (除了 192.168.1.251 )
[root@mail ~]# vim /etc/hosts.allow
#
# hosts.allow This file describes the names of the hosts which are
# allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: 192.168.1. EXCEPT 192.168.1.251 :spawn echo "`date`, login attempt from %c to %s." >> /var/log/tcpwrapper.log
[root@mail ~]# vim /etc/hosts.deny # 内容没变
#
# hosts.deny This file describes the names of the hosts which are
# *not* allowed to use the local INET services, as decided
# by the '/usr/sbin/tcpd' server.
#
in.telnetd: ALL :spawn echo "`date`, login attempt from %h " >> /var/log/tcpwrapper.log
再登录一次看看
windows 不能访问了,记入了失败的日志
直接跳到如下图的样子了
[root@mail ~]# tail /var/log/tcpwrapper.log #最后一行,看到了失败的日志
somebody entered Sun Aug 23 18:28:15 CST 2020
somebody entered Sun Aug 23 18:28:53 CST 2020
Sun Aug 23 18:55:56 CST 2020, login attempt from 192.168.1.251 to in.telnetd@192.168.1.75.
Sun Aug 23 19:00:08 CST 2020, login attempt from 192.168.1.251
[root@mail ~]#