美文网首页
MySQL: 如何判定连接用的IPV6

MySQL: 如何判定连接用的IPV6

作者: 重庆八怪 | 来源:发表于2022-11-28 09:02 被阅读0次

    笔记,仅供参考。


    MySQL 支持IPV6 连接,但是收到bind_address参数影响,如下:
    • 设置 0.0.0.0 为IPV4
    • 设置* 为IPV6和VIP4都支持
    • 设置 对应IP ,则在对应IP上进行监听
    • 设置:: 为IPV6

    具体可以查看代码listen 端口的建立方式,查看bind_address是如何生效的。

    Linux的net.ipv6.conf.all.disable_ipv6代表是否禁用IPV6协议
    [root@pxctest6 ~]# more /etc/sysctl.conf 
    # sysctl settings are defined through files in
    # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
    #
    # Vendors settings live in /usr/lib/sysctl.d/.
    # To override a whole file, create a new file with the same in
    # /etc/sysctl.d/ and put new settings there. To override
    # only specific settings, add a file with a lexically later
    # name in /etc/sysctl.d/ and put new settings there.
    #
    # For more information, see sysctl.conf(5) and sysctl.d(5).
    net.ipv6.conf.all.disable_ipv6=0
    
    • 进行ping测试
      ping6 fe80::20c:29ff:fe7d:9453%ens33
    MySQL通过ipv6连接测试和连接协议的判定

    [root@pxctest6 ~]# mysql -u mytest -p'gelc1233' -h 'fe80::20c:29ff:fe7d:9453%ens33' -P 3370
    mysql: [Warning] Using a password on the command line interface can be insecure.
    ERROR 1045 (28000): Access denied for user 'mytest'@'fe80::20c:29ff:fe67:d1bf%ens33' (using password: YES)

    连接可以看到报错也是用户+地址

    需要注意的是,是否使用ipv6协议是通过mysql客户端进行判断的,根据其输入的IP地址类型进行判定的,主要函数为getaddrinfo,进行判定参考函数csm_begin_connect,host为IP,port_buf为端口,如下:

    gai_errno = getaddrinfo(host, port_buf, &hints, &res_lst);
    res_lst为一个结果的链表,多种type和协议类型等组合?
    
    • 获取IP的协议类型
    • 将访问的地址

    等一起封装到res_lst

    去掉IPV6支持可以是
    • 设置bind_address=0.0.0.0
    • 设置net.ipv6.conf.all.disable_ipv6=1,关闭IPV6协议栈支持
    另外是否为socket本地连接,两个方式
    • 开general log 本地连接为socket连接,否则为tcp。
    • 看strace,在check_connect函数里面走的流程不一样,tcp连接需要通过函数getpeername函数获取远端IP。
    下面模拟一下MySQL client 判定受用IPV4还是IPV6协议栈时用到的函数getaddrinfo
    #include<stdlib.h>
    #include<stdio.h>
    #include <assert.h>
    #include <unistd.h>
    #include <signal.h>
    #include<netdb.h>
    
    const char* hostv6 = "fe80::20c:29ff:fe7d:9453";
    const char* hostv4 = "192.168.1.1";
    
    int main(void)
    {
      
      const char *port_buf = "3306";
      struct addrinfo *res_lst, hints;
      struct addrinfo *t_res;
      
      int errno = 0;
      const char* t1 = hostv6;
      const char* t2 = hostv4; 
      printf("AF_INET6 :%d\n",AF_INET6);
      printf("AF_INET  :%d\n",AF_INET);
      printf("SOCK_STREAM :%d\n",SOCK_STREAM);
      printf("SOCK_DGRAM :%d\n",SOCK_DGRAM);
      printf("IPPROTO_IP :%d\n",IPPROTO_IP);
      printf("IPPROTO_TCP %d\n",IPPROTO_TCP);
      printf("IPPROTO_UDP %d\n",IPPROTO_UDP);
      
      
      
      errno = getaddrinfo(t1, port_buf, &hints, &res_lst);
      
      /*
      if(errno != 0)
      {
        perror("err:");
        exit(0);
      
      }
      */
      
      for (t_res = res_lst; t_res; t_res = t_res->ai_next)
      {
       printf("socket, family: %d  type: %d  proto: %d\n",t_res->ai_family, t_res->ai_socktype, t_res->ai_protocol);
      }
      
      errno = getaddrinfo(t2, port_buf, &hints, &res_lst);
     
      /*
      if(errno != 0)
      {
        perror("err:");
        exit(0);
      
      }
      */
      
      for (t_res = res_lst; t_res; t_res = t_res->ai_next)
      {
       printf("socket, family: %d  type: %d  proto: %d\n",t_res->ai_family, t_res->ai_socktype, t_res->ai_protocol);
      }
      return 0;
    }
    
    
    AF_INET6 :10
    AF_INET  :2
    SOCK_STREAM :1
    SOCK_DGRAM :2
    IPPROTO_IP :0
    IPPROTO_TCP 6
    IPPROTO_UDP 17
    socket, family: 10  type: 1  proto: 6
    socket, family: 10  type: 2  proto: 17
    socket, family: 10  type: 3  proto: 0
    socket, family: 2  type: 1  proto: 6
    socket, family: 2  type: 2  proto: 17
    socket, family: 2  type: 3  proto: 0
    

    相关文章

      网友评论

          本文标题:MySQL: 如何判定连接用的IPV6

          本文链接:https://www.haomeiwen.com/subject/yajlfdtx.html