zoukankan      html  css  js  c++  java
  • 基于HTTP 协议认证介绍与实现

     

    基于HTTP 协议认证介绍与实现2013-06-15 10:27 by youxiachai, 443 阅读, 0 评论, 收藏编辑

    一直对http 的头认证有兴趣,就是路由器的那种弹出对话框输入账号密码怎么实现一直不明白,最近,翻了一下http 协议,发现这是一个RFC 2617的实现,所以写篇文章介绍一下吧.

    这是一个用于web浏览器或其他客户端在请求时提供用户名和密码的登录认证,要实现这个认证很简单:

    我们先来看下协议里面怎么定义这个认证的. 1. 编码: 将用户名 追加一个 冒号(':')接上密码,把得出的结果字符串在用Base64算法编码.

    1. 请求头: Authorization: 认证类型 编码字符串

    来看一下客户端如何发起请求例如,有一个用户名为:tom, 密码为:123456 怎么认证呢?

    步骤如下 1. 编码

    Base64('tom:123456') == dG9tOjEyMzQ1Ng==;

    1. 把编码结果放到请求头当中

      Authorization: Basic dG9tOjEyMzQ1Ng==

    请求样例客户端

    1
    2
    3
    GET / HTTP/1.1
    Host: localhost
    Authorization: Basic dG9tOjEyMzQ1Ng

    服务端应答

    1
    2
    3
    4
    HTTP/1.1 200 OK
    Date: Thu, 13 Jun 2013 20:25:37 GMT
    Content-Type: application/json; charset=utf-8
    Content-Length: 53

    如果没有认证信息

    1
    2
    3
    HTTP/1.1 401 Authorization Required
    Date: Thu, 13 Jun 2013 20:25:37 GMT
    WWW-Authenticate: Basic realm="Users"

    验证失败的时候,响应头加上WWW-Authenticate: Basic realm="请求域".

    这种http 基本实现,几乎目前所有浏览器都支持.不过,大家可以发现,直接把用户名和密码只是进行一次base64 编码实际上是很不安全的,因为对base64进行反编码十分容易,所以这种验证虽然简便,但是很少会在公开访问的互联网使用,一般多用在小的私有系统,例如,你们家里头的路由器,多用这种认证方式.

    这个认证可以看做是基本认证的增强版本,使用随机数+密码进行md5,防止通过直接的分析密码MD5防止破解. 摘要访问认证最初由 RFC 2069 (HTTP的一个扩展:摘要访问认证)中被定义加密步骤:

    1. ha1

    2. ha2 

    3. res

    后来发现,就算这样还是不安全(md5 可以用彩虹表进行攻击),所以在RFC 2617入了一系列安全增强的选项;“保护质量”(qop)、随机数计数器由客户端增加、以及客户生成的随机数。这些增强为了防止如选择明文攻击的密码分析。

    d1

    1. 如果 qop 值为“auth”或未指定,那么 HA2 为

      d3

    2. 如果 qop 值为“auth-int”,那么 HA2 为

      d3

    3. 如果 qop 值为“auth”或“auth-int”,那么如下计算 response:

      d4

    4. 如果 qop 未指定,那么如下计算 response:

      d5

    好了,知道加密步骤,下面我们用文字来描述一下;

    最后,我们的response 由三步计算所得. 1. 对用户名、认证域(realm)以及密码的合并值计算 MD5 哈希值,结果称为 HA1。

    HA1 = MD5( "tom:Hi!:123456" ) = d8ae91c6c50fabdac442ef8d6a68ae8c

    1. 对HTTP方法以及URI的摘要的合并值计算 MD5 哈希值,例如,"GET" 和 "/index.html",结果称为 HA2。

      HA2 = MD5( "GET:/" ) = 71998c64aea37ae77020c49c00f73fa8

    2. 最后生成的响应码

      Response = MD5("d8ae91c6c50fabdac442ef8d6a68ae8c:L4qfzASytyQJAC2B1Lvy2llPpj9R8Jd3:00000001:c2dc5b32ad69187a
      :auth:71998c64aea37ae77020c49c00f73fa8") = 2f22e6d56dabb168702b8bb2d4e72453;

    RFC2617 的安全增强的主要方式:

    发起请求的时候,服务器会生成一个密码随机数(nonce)(而这个随机数只有每次"401"相应后才会更新),为了防止攻击者可以简单的使用同样的认证信息发起老的请求,于是,在后续的请求中就有一个随机数计数器(cnonce),而且每次请求必须必前一次使用的打.这样,服务器每次生成新的随机数都会记录下来,计数器增加.在RESPONSE 码中我们可以看出计数器的值会导致不同的值,这样就可以拒绝掉任何错误的请求.

    请求样例(服务端 qop 设置为"auth")

    客户端 无认证

    1
    2
    GET / HTTP/1.1
    Host: localhost

    服务器响应(qop 为 'auth')

    1
    2
    3
    HTTP/1.1 401 Authorization Required
    Date: Thu, 13 Jun 2013 20:25:37 GMT
    WWW-Authenticate: Digest realm="Hi!", nonce="HSfb5dy15hKejXAbZ2VXjVbgNC8sC1Gq", qop="auth"

    客户端请求(用户名: "tom", 密码 "123456")

    1
    2
    3
    4
    5
    6
    7
    8
    9
    GET / HTTP/1.1
    Host: localhost
    Authorization: Digest username="tom",
                         realm="Hi!",
                         nonce="L4qfzASytyQJAC2B1Lvy2llPpj9R8Jd3",
                         uri="/",
                         qop=auth,
                         nc=00000001,
                         cnonce="c2dc5b32ad69187a",                     response="2f22e6d56dabb168702b8bb2d4e72453"

    服务端应答

    1
    2
    3
    4
    HTTP/1.1 200 OK
    Date: Thu, 13 Jun 2013 20:25:37 GMT
    Content-Type: application/json; charset=utf-8
    Content-Length: 53

    注意qop 设置的时候慎用:auth-int,因为一些常用浏览器和服务端并没有实现这个协议.

    NFS服务基本配置及使用

    一、安装
    CENTOS或RHL默认就已安装,如果没有安装的话,通过yum安装即可:
    yum install nfs-utils
    yum install portmap
     
    UBUNTU系统,通过apt-get安装:
    apt-get install  nfs-kernel-server

    二、配置
    1、配置文件定义
    NFS的配置文件为 /etc/exports,内容格式如下:
    <共享目录> 客户端1(选项) [客户端2(选项) ...]
     共享目录:NFS共享给客户机的目录。
     客户端:网络中可以访问此目录的主机。多个客户端以空格分隔。
     选项:设置目录的访问权限、用户映射等,多个选项以逗号分隔。
    例如:
    /opt/public 192.168.1.0/24(rw,insecure,sync,all_squash,anonuid= 65534,anongid=65534)

    2、客户端的指定方式
    指定ip地址的主机:192.168.0.100
    指定子网中的所有主机:192.168.0.0/24 或 192.168.0.0/255.255.255.0
    指定域名的主机:nfs.test.com
    指定域中的所有主机:*.test.com
    所有主机:*
     
    3、选项说明
    ro:共享目录只读;
    rw:共享目录可读可写;
    all_squash:所有访问用户都映射为匿名用户或用户组;
    no_all_squash(默认):访问用户先与本机用户匹配,匹配失败后再映射为匿名用户或用户组;
    root_squash(默认):将来访的root用户映射为匿名用户或用户组;
    no_root_squash:来访的root用户保持root帐号权限;
    anonuid=<UID>:指定匿名访问用户的本地用户UID,默认为nfsnobody(65534);
    anongid=<GID>:指定匿名访问用户的本地用户组GID,默认为nfsnobody(65534);
    secure(默认):限制客户端只能从小于1024的tcp/ip端口连接服务器;
    insecure:允许客户端从大于1024的tcp/ip端口连接服务器;
    sync:将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
    async:将数据先保存在内存缓冲区中,必要时才写入磁盘;
    wdelay(默认):检查是否有相关的写操作,如果有则将这些写操作一起执行,这样可以提高效率;
    no_wdelay:若有写操作则立即执行,应与sync配合使用;
    subtree_check(默认) :若输出目录是一个子目录,则nfs服务器将检查其父目录的权限;
    no_subtree_check :即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;

    三、NFS相关命令
    1、exportfs
    不重启nfs服务应用更新,相关选项如下:
    -a 全部挂载或卸载 /etc/exports中的内容
    -r 重新读取/etc/exports 中的信息 ,并同步更新/etc/exports、/var/lib/nfs/xtab
    -u 卸载单一目录(和-a一起使用为卸载所有/etc/exports文件中的目录)
    -v 在export的时候,将详细的信息输出到屏幕上。

    2、nfsstat
    查看NFS的运行状态。
     
    3、rpcinfo
    查看rpc服务注册情况。
    相关选项:
    -p 显示所有的端口与程序信息。
    示例:
    rpcinfo -p localhost  #列出本机的RPC注册状况。

    3、showmount
    查询nfs共享目录信息,相关选项如下:
    -a 显示已经于客户端连接上的目录信息
    -e IP或者hostname 显示此IP地址分享出来的目录
     
    示例:
    showmount -e localhost  #查询本机nfs共享目录情况
    showmount -a localhost  #查询本机共享目录连接情况

    四、linux客户端挂载共享目录
    1、临时挂载
    通过mount挂载,例如:
    mount -t nfs 192.168.1.1:/opt/public /mnt/public

    2、启动挂载
    将挂载信息写入fstab文件
    vi /etc/fstab
    192.168.1.1:/opt/public /mnt/public nfs defaults
    保存退出
    mount -a
     
    3、基于autofs自动挂载
    autofs可以在使用到挂载文件系统时自动挂载,当长时间不使用时自动卸载,配置灵活方便。
    安装autofs:
    centos,rhl:
    yum install autofs
    ubuntu:
    apt-get install autofs
     
    编辑主配置文件/etc/auto.master,在末尾添加需挂载的目录信息。
    格式为:本机挂载主目录 对应的加载配置文件名 -挂载参数
    挂载参数同mount的挂载参数,多个参数以逗号分隔。此处的挂载参数可以与对应的加载配置文件中定义的参数产生叠加作用。
    示例:
    vi /etc/auto.master
    #本机挂载主目录为/mnt,与之对应的加载配置文件为/etc/auto.nfs
    /mnt /etc/auto.nfs
    保存退出
     
    编辑加载配置文件,添加需要挂载的文件系统。
    格式为:挂载目录 -挂载参数 挂载文件系统
    挂载参数同mount的挂载参数,多个参数以逗号分隔。
    示例:
    vi /etc/auto.nfs
    public -rw,bg,soft,rsize=32768,wsize=32768,nosuid,noexec,nodev 192.168.1.1:/opt/public
    保存退出
     
    重启autofs
    /etc/init.d/autofs restart
     
    五、windows客户端挂载共享目录
    1、到M$网站下载SFU3.5,下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=274
     
    2、在本地建立group文件,内容如下:
    root:x:0:
     
    3、在本地建立passwd文件,内容如下:
    root:x:0:0:root:/root:/bin/bash
     
    4、解压并安装SFU,选择定制安装,在 User Name Mapping界面,选择Password and group files,进入下一步分别输入前面建立的passwd和group文件完整路径,点击下一步完成安装。
     
    5、配置SFU
    在开始菜单的程序中找到Windows Services for Unix,点击Services for Unix Administration。在设置界面点击User Name Mapping,切换到Map标签页,点击 show group Maps,在windows group name 和unix group name框中分别输入guests和root,然后点击add。然后点击 show User Maps,在windows user name 和unix user name框中分别输入guest和root,然后点击add。最后点击右上角的apply应用设置。

    6、确保windows系统中的guest帐号可用
    运行gpedit.msc
    在Computer Configuration->Windowns Settings->Security Settings->Local Policies->User Right Assignment->Deny access to this computer from the network:去掉Guest。 并检查其它相关项是否有允许Guest访问。
    在 Computer Configuration->Windowns Settings->Security Settings->Local Policies->Security Options->Network access->Sharing and security model for local accounts:选择经典方式:Classic-Local users authenticate as themselves。
     
    7、通过网上邻居映射网络驱动器、cmd下mount(例如:mount \\192.168.1.100\opt\public z:)或者直接在地址栏输入地址(例如:\\192.168.1.100\opt\public)挂载共享目录。
     
    六、NFS权限设定
    1、普通用户
    if ( 设置了all_squash ) then
         访问用户强制映射为指定nfs匿名用户;
    else
         if ( NFS server上有同名用户 ) then
              访问用户映射为服务器上的同名用户;
         else
             访问用户映射成nfsnobody;
     
    2、root
    if ( 同时设置了no_root_squash和all_squash ) then
         访问用户映射为指定nfs匿名用户;
    else
         if ( 设置了no_root_squash ) then
              来访root映射为指定服务器上的root用户;
         else
              if ( 设置了all_squash ) then
                   访问用户映射为指定nfs匿名用户;
              else
                  访问用户映射成nfsnobody;
     
    七、mount相关参数
    ro 以只读模式加载。
    rw 以可读写模式加载。
    sync 以同步方式执行文件系统的输入输出动作。
    async 以非同步的方式执行文件系统的输入输出动作。
    defaults 使用默认的选项。默认选项为rw、suid、dev、exec、anto nouser与async。
    atime 每次存取都更新inode的存取时间,默认设置,取消选项为noatime。
    noatime 每次存取时不更新inode的存取时间。
    dev 可读文件系统上的字符或块设备,取消选项为nodev。
    nodev 不读文件系统上的字符或块设备。
    exec 可执行二进制文件,取消选项为noexec。
    noexec 无法执行二进制文件。
    auto 必须在/etc/fstab文件中指定此选项。执行-a参数时,会加载设置为auto的设备,取消选取为noauto。
    noauto 无法使用-a参数来加载。
    suid 启动set-user-identifier(设置用户ID)与set-group-identifer(设置组ID)设置位,取消选项为nosuid。
    nosuid 关闭set-user-identifier(设置用户ID)与set-group-identifer(设置组ID)设置位。
    user 普通用户可以执行加载操作。
    nouser 普通用户无法执行加载操作,默认设置。
    remount 重新加载设备。通常用于改变设备的设置状态。
    rsize 读取数据缓冲大小,默认设置1024。
    wsize 写入数据缓冲大小,默认设置1024。
    fg 以前台形式执行挂载操作,默认设置。在挂载失败时会影响正常操作响应。
    bg 以后台形式执行挂载操作。
    hard 硬式挂载,默认设置。如果与服务器通讯失败,让试图访问它的操作被阻塞,直到服务器恢复为止。
    soft 软式挂载。如果服务器通讯失败,让试图访问它的操作失败,返回一条出错消息。这项功能对于避免进程“挂”在无关紧要的安装操作上来说非常有用。
    retrans=n 指定在以软方式安装的文件系统上,在返回一条出错消息之前重复发出请求的次数。
    nointr 不允许用户中断,默认设置。
    intr 允许用户中断被阻塞的操作(并且让它们返回一条出错消息)。
    timeo=n 设置请求的超时时间(以十分之一秒为单位)。

    注:
    automounter专用参数
    fstype=  用于指定一个文件系统的类型(如果要挂载的文件系统不是NFS的话),mount是不能用的。
     

    八、注意事项
    1、NFS服务器关机时要确保NFS没有客户端连接,否则无法正常关机 。可以先强制停止或杀死nfs服务。
    2、windows客户端挂载共享目录不支持utf-8编码,因此可能会出现中文乱码。可以通过修改服务器local的默认编码来解决。
    lykyl原创,转载请注明出处)
     
    分类: LINUX
    标签: linuxNFS
  • 相关阅读:
    【Linux】Linux服务器(centos7)安装配置 redis
    【java】使用 starter 的方式在 SpringBoot 中整合 Shiro
    【Docker】使用 Docker 基于centos7 构建 java 环境容器
    c#经典三层框架中的SqlHelper帮助类
    SOD框架的Model、连接数据库及增删改查
    用bat文件更改ip地址
    postgresql 创建并使用uuid作为唯一主键
    postgresql 查询字符串中是否包含某字符的几种写法
    pycharm激活码
    c# DataTable第二行改为各列标题字段
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3137880.html
Copyright © 2011-2022 走看看