8.5 MD5选项

TCP MD5选项通过在BGP协议的TCP报文段中携带MD5摘要,增强安全性,防止报文伪造。RFC 2385定义了该选项,要求每个报文携带16字节的digest。在Linux内核中,需启用CONFIG_TCP_MD5SIG编译选项,并使用TCP_MD5SIG socket选项导入密钥。应用双方需导入对方地址及共享密钥以启用MD5选项进行安全通信。

8.5.1 选项功能

  TCP MD5选项用于强化BGP协议的安全性,其基本原理是在TCP报文段的选项中携带MD5摘要。这个摘要的行为类似于这个报文的签名,其中包含这只有通信双方才能理解的信息。如果BGP协议使用TCP作为其传输层协议,使用MD5选项会有效减少安全隐患。

8.5.2 协议规范

  TCP MD5选项的规范由RFC 2385提出。

  每一个TCP报文段都应该携带MD5选项(包含一个16字节的MD5 digest)。MD5算法的输入数据如下(严格按照顺序):

(1)TCP伪首部(源IP,目的IP,填充0的协议号,报文长度)

(2)TCP首部,不包含选项,checksum计为0

(3)TCP数据段(如果有)

(4)密钥或口令,这个需要TCP通信双方和连接规范都知晓

  接收方收到TCP报文时,必须根据报文的信息以及自己的密钥来计算digest,并与报文中的digest进行比较。如果比较失败则必须丢弃报文,并且不能产生任何响应。这样就大大增加了攻击者通过伪造TCP报文实施对BGP协议的攻击的难度。

8.5.3 开启方法

  Linux内核需要开启CONFIG_TCP_MD5SIG编译选项才能支持TCP MD5选项功能。应用进程还需要使用TCP_MD5SIG socket选项导入密钥:

struct tcp_md5sig cmd;
...
setsockopt(sockfd, SOL_TCP, TCP_MD5SIG,  &cmd, sizeof(cmd));
  其中struct tcp_md5sig的定义为:
191 #define TCP_MD5SIG_MAXKEYLEN    80
192 
193 struct tcp_md5sig {
194     struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
195     __u16   __tcpm_pad1;                /* zero */
196     __u16   tcpm_keylen;                /* key length */
197     __u32   __tcpm_pad2;                /* zero */
198     __u8    tcpm_key[TCP_MD5SIG_MAXKEYLEN];     /* key (binary) */
199 };

  其中tcpm_addr是要通信的服务器的地址(IP地址、端口等),如果sockfd要与N个机器进行通信则需要调用N此setsockopt系统调用来导入相应的地址-密钥对。举个例子,如果A要与B通信,则A需要调用setsockopt来导入B的地址和一个密钥Key,而B也需要调用setsockopt来导入A的地址和与A相同的密钥Key,然后双方才能使用MD5选项进行通信。

8.5.4 内核实现

  TCP_MD5SIG socket选项对应的内核代码为:

2371 static int do_tcp_setsockopt(struct sock *sk, int level,
2372         int optname, char __user *optval, unsigned int optlen)
2373 {
...
2605 #ifdef CONFIG_TCP_MD5SIG
2606     case TCP_MD5SIG:
2607         /* Read the IP->Key mappings from userspace */
2608         err = tp->af_specific->md5_parse(sk, optval, optlen); //指向tcp_v4_parse_md5_keys函数
2609         break;
2610 #endif
...
  tcp_v4_parse_md5_keys用于导入MD5签名的密钥(key):

1083 static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
1084                  int optlen)
1085 {  
1086     struct tcp_md5sig cmd;
1087     struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr;
1088    
1089     if (optlen < sizeof(cmd))
1090         return -EINVAL;
1091    
1092     if (copy_from_user(&cmd, optval, sizeof(cmd)))
1093         return -EFAULT;
1094 
1095     if (sin->sin_family != AF_INET)
1096         return -EINVAL;
1097 
1098     if (!cmd.tcpm_key || !cmd.tcpm_keylen)
1099         return tcp_md5_do_del(sk, (union 
### 如何在 Rocky Linux 8.5 上升级 OpenSSH 为了确保系统的安全性,在 Rocky Linux 8.5 中升级 OpenSSH 至最新版本是一个重要的维护工作。以下是详细的步骤说明: #### 准备阶段 确认当前使用的 OpenSSH 版本,可以使用如下命令来查看: ```bash ssh -V ``` #### 更新软件包列表 更新本地的 yum 数据库以获取最新的可用软件包信息: ```bash sudo dnf update -y ``` #### 添加 EPEL 源 由于官方源可能不提供最新的 OpenSSH 版本,因此推荐添加额外的扩展源如 EPEL 来获得更广泛的软件支持: ```bash sudo dnf install epel-release -y ``` #### 安装或编译更高版本的 OpenSSH 如果希望直接从二进制安装,则可以通过以下方式尝试安装来自第三方仓库的安全增强型 SSH 实现或其他社区贡献的新版本;然而对于特定需求或者想要完全掌控配置的情况下可以选择自行下载并编译源码。 ##### 方法一:通过 DNF 安装新版本(假设目标版本为 8.7p1) 先移除旧版本防止冲突: ```bash sudo dnf remove openssh-server openssh-clients -y ``` 接着安装指定版本: ```bash sudo dnf install https://example.com/path/to/openssh-8.7p1.rpm -y ``` 注意这里的 URL 和路径应替换为你实际找到可信来源处提供的 RPM 文件链接[^2]。 ##### 方法二:手动编译安装 当需要自定义选项或是追求绝对最新特性时,可以从官方网站获取 tarball 并按照标准流程进行编译部署: ```bash cd /usr/local/src/ wget http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.7p1.tar.gz tar zxfv openssh-8.7p1.tar.gz cd openssh-8.7p1 ./configure --prefix=/usr \ --sysconfdir=/etc/ssh \ --with-md5-passwords \ --with-pam \ --with-selinux\ --without-openssl-header-check make && sudo make install ``` 完成上述任一步骤之后记得重启服务使更改生效: ```bash sudo systemctl restart sshd.service ``` 最后再次验证版本号是否正确变更: ```bash ssh -V ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值