需求背景 服务器已经搭建一个opendlap在docker里面运行 映射端口为389->389,现在需要另外创建一个容器搭建svn服务器,并且接入ldap来验证用户登录。
docker hub已搭好的fastmaybe/svn-server
docker pull fastmaybe/svn-server
环境说明
- apache作为前端访问入口和功能整合
- svn的认证使用apache代理openLDAP完成
- svn的权限和授权受限于svn本身的机制,目前任然使用其原生配置文件方式。
- openLDAP提供用户身份认证数据提供和用户统一管理
直接开始记录过程:
先附上常见的docker命令
service docker start:启动docker
service docker stop:停止docker
service docker restart:重启docker
docker images:查看所有镜像
docker ps:查看运行中的容器
docker ps -a:查看所有容器
docker logs xxx:查看xxx日志
docker run xxx:运行xxx
docker start -i name:启动name容器
docker pause xxx:暂停xxx名字容器
docker unpause xxx:恢复xxx名字容器
docker stop xxx:停止xxx名字容器
docker rmi xxx:删除xxx名字镜像
docker tag aaa bbb:更改aaa容器名字为bbb
docker exec -it xxx bash:进入xxx容器交互界面
docker search xxx:搜索xxx镜像
docker pull xxx:拉取xxx镜像
docker save xxx > /home/xxx.tar.gz:导出xxx镜像到/home/xxx.tar.gz
docker load < /home/xxx.tar.gz:导入文件/home/xxx.tar.gz到镜像
docker network create net1:创建net1网段
docker network inspect net1:查看net1网段
docker network rm net1:删除net1网段
docker卷:
docker volume create --name xxx:创建xxx卷
docker inspect xxx:查看xxx卷
docker volume rm xxx:删除xxx卷
启动容器:
docker run -it --name rename -p 9000:8080 -p 9001:8081 -v /home/workspace:/soft --privileged xxx bash
-d:创建出的容易在后台运行
-it:启动容器后开启进入容器交互页面
--name:给容器起个名字rename
-p:把真实宿主机9000端口映射到容器8080端口
bash:启动容器运行的是bash指令
-v:把宿主机目录/home/workspace映射到容器目录/soft,":"分隔
--privileged:映射文件最高权限,可以进行读写操作
一.创建一个容器
由于openldap已经在另一个容器运行 此处就不安装openldap
先区docker-hub拉去一个基础镜像centos,
运行镜像创建一个容器 命令如下
docker run -itd
--name svn-server
-p 91:80 -p 3690:3690
-v /opt/svn:/opt/svn
--privileged
镜像
/usr/sbin/int
先说一下上面命令什么意思:
- –name 启动容器以什么命名标示 容器
- itd 创建出的容易在后台运行
-
- docker一般命令是 -d在后台运行 因为此处遇到 加上-d参数启动后还是马上退出 因此加-itd
- -p 端口映射 宿主机端口:容器端口
- -v 文件挂载 设置后删除容器 宿主机的文件不会被删
- –privileged 映射文件最高权限,可以进行读写操作
- /usr/sbin/int 此处只是单独因为后续操作需要使用 systemctl服务 因此在启动容器的时候就需要加上此参数
容器起动后会返回一个id
docker ps查看正在运行的容器
- 运行 docker exec -it svn-server bash 进入容器
进入容器后:
二.安装Apache服务
yum -y install httpd
三. 安装Subversion服务
yum -y install subversion
yum -y install mod_dav_svn (Apache httpd module for Subversion server)
四.配置httpd及subversion服务
- 1.拷贝subversion.conf模板
cp /etc/httpd/conf.modules.d/10-subversion.conf /etc/httpd/conf.d/subversion.conf
- 2.authz_svn和dav_svn模块
打开subversion.conf文件后默认有加载authz_svn和dav_svn模块,模块的路径为 /etc/httpd/modules
- 3.配置subversion.conf
- `下列配置中有几点做下说明:
SVNParentPath:svn服务路径
AuthzSVNAccessFile:svn的权限配置文件
AuthLDAPURL:搭建的openldap url地址
AuthLDAPBindDN:配置 openldap的cn、dc
AuthLDAPBindPassword:配置openldap的管理员密码
AuthName:写死就行
AuthType:验证类型,Basic使用账号密码验证
AuthBasicProvider:ldap写死不解释
AuthzLDAPAuthoritative:这个搭配最下面“Require ldap-user”使用,on表示只要求验证ldap用户,别的不认;off则可以使用svn的账号和ldap混合账号登陆
Require:ldap-user或者valid-user,你要是只用ldap账号登陆的话就填写第一个
找到apache服务器的安装路径,一般在/etc/httpd/下,在conf.d目录下有一个subversion.conf文件(没有的话请自行创建),打开它,先上我的配置:
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
LoadModule dontdothat_module modules/mod_dontdothat.so
<Location /opt/svn>
DAV svn
SVNParentPath /opt/svn
SVNListParentPath On
AuthzSVNAccessFile /opt/svn/authz
AuthBasicProvider ldap
AuthType Basic
AuthName "Subversion repository"
AuthLDAPURL "ldap://192.168.88.188:389/dc=hongxue,dc=com?uid?sub?(objectClass=*)"
AuthLDAPBindDN "cn=root,dc=hongxue,dc=com" #管理员 (注意:如果openldap配置了可以匿名访问 此处可以不要)
AuthLDAPBindPassword "123456" #密码 (注意:如果openldap配置了可以匿名访问 此处可以不要)
Require valid-user
</Location>
-
在解释AuthLDAPURL|AuthLDAPBindDN|AuthLDAPBindPassword的时候要先讲一下LDAP服务器认证过程,方便理解:
客户端(httpd)使用提供的URL(AuthLDAPURL)进行验证的时候,并不是直接验证输入的账 号密码,因为LDAP服务器在验证的时候要使用DN(每个节点用户的唯一标识)和密码来进行登陆验证的,但是DN一般来说比较长,诸如:“cn=xxx,ou=xxx,ou=xxx,dc=xxx,dc=xxx”,这种光输入的时候就烦气了,所以要想使用简短的用户名来登陆的时候,一般的做法是在某个节点用户上添加一个属性,比如mobile(手机号),Email(邮箱),user name或者uid(用户名),然后使用这个属性的值来登陆。
当用户输入这个属性值和密码的时候,客户端(httpd服务器)先使用AuthLDAPBindDN和AuthLDAPBindPassword作为用户名和密码登陆,根据AuthLDAPURL指定的查询规则(AuthLDAPURL的查询规则一会再说)来查找用户输入的属性的值有没有,如果查找的条数为0或者大于1,则返回错误,如果查找的条数等于1,则使用查找到的这个条目的DN和用户输入的密码进行登陆验证,成功则成功,失败则失败,这就是OpenLDAP的验证过程。
AuthLDAPBindDN|AuthLDAPBindPassword:就是用于查找用户的账号密码了
AuthLDAPURL:
对应上面那个url:协议名称://[ip地址或者域名]:[端口号]/[baseDN]?[attr]?[scope]?[filter]
baseDN:指定开始搜索节点的名称
attr:就是用户输入的属性键,默认是"uid",我使用的是uid,还可以使用cn,mobile,Email等。。。
scope:one,sub,base三者之一,默认sub
filter:过滤器,默认(objectclass=*) -
总结一下LDAP的认证过程分为两部:
-
- 搜索用户是否存在LDAP服务器中:配置文件中配置的AuthLDAPBindDN和AuthLDAPBindPassword两个属性主要目的就是为了登陆LDAP服务器搜索属性(uid)是否只有一条,如果服务器允许匿名访问则这两个配置可以不需要,但一般为了安全性都会关闭LDAP的匿名访问,新建一个只读权限的账号配置到这里即可
-
- 使用用户输入的属性值(uid)和密码进行登陆验证
-
4.启动Apache服务
systemctl start httpd.service
systemctl status httpd.service
如有报错:Unknown Authn provider: ldap
解决:yum -y install mod_ldap
- 5、svn服务配置
mkdir /opt/svn # 创建svn版本库目录
svnserve -d -r /opt/svn # 启动svn服务
svnadmin create Test # 创建一个svn版本库
chown apache.apache -R /opt/svn # 授权,不然web会有errorlog
- 6.svn授权
vim /opt/svn/authz
添加如下内容:
[groups]
admin=yuan
users=test1,test2
[/] # /目录下
@admin = rw #读写权限
[Test:/] # /Test
@users = r #只读权限
这里的yuan,test1,test2是只用户输入的属性的值(LDAP服务器中某个用于登陆的节点的属性值),如果你没配置这里的权限,用户虽然登陆成功了,但是没有相应的权限页面会提示没权限查看的,users后面跟多个以","分割的用户名(你设置的查询规则按什么查询就是什么)
以上为一种验证方式:即openldap控制用户是否通过验证(subversion.conf 中的 Require valid-user配置,即都要求验证用户),而权限控制在svn的权限文件里面来控制。
https://blog.csdn.net/lansine2005/article/details/20362591
http://httpd.apache.org/docs/current/mod/core.html#limit
可以用另一种方式控制,将subversion.conf中的 svn验证文件注释掉,贴上常用两种配置。
- 验证组
<Location /opt/svn/>
DAV svn
SVNParentPath /opt/svn
SVNListParentPath On
#AuthzSVNAccessFile /opt/svn/authz #注释掉本地的svn权限控制 如果需要 也可以放开设置,配合下面配置精确到哪个文件可以访问读写权限。
AuthBasicProvider ldap
AuthType Basic
AuthName "Subversion repository"
AuthLDAPURL "ldap://192.168.88.188:389/ou=people,dc=secmask,dc=com?uid?sub?(objectClass=*)"
` <Limit GET PROPFIND OPTIONS REPORT> #
#读取需要验证 是不是属于此节点下(控制读权限,验证是否属于某个节点(组))
Require ldap-group cn=svn_get,cn=svn,ou=Group,dc=secmask,dc=com
</Limit>
<LimitExcept GET PROPFIND OPTIONS REPORT>
#写 操作需要验证 是不是属于此节点下(控制写权限,验证是否属于某个节点(组))
Require ldap-group cn=svn_write,cn=svn,ou=Group,dc=secmask,dc=com
</LimitExcept>
</Location>
- 或者验证用户
<Location /opt/svn/>
DAV svn
SVNParentPath /opt/svn
SVNListParentPath On
#AuthzSVNAccessFile /opt/svn/authz #注释掉本地的svn权限控制 如果需要 也可以放开设置,配合下面配置精确到哪个文件可以访问读写权限。
AuthBasicProvider ldap
AuthType Basic
AuthName "Subversion repository"
AuthLDAPURL "ldap://192.168.88.188:389/ou=people,dc=secmask,dc=com?uid?sub?(objectClass=*)"
` <Limit GET PROPFIND OPTIONS REPORT> #
#读取需要验证 用户
Require valid-user
</Limit>
<LimitExcept GET PROPFIND OPTIONS REPORT>
#写 操作需要验证 是不是属于此节点下(控制写权限,验证用户)
Require ldap-group cn=svn_write,cn=svn,ou=Group,dc=secmask,dc=com
</LimitExcept>
</Location>
总结:
- ldap轻量级目录访问协议,Ldap是一种目录式的数据存储方式,类似于数据库,区别于常用的关系型数据库,都是用来存储数据的,知识存储的方式不同而已;此处可以理解为数据库 验证时候需要数据库的用户密码登录进去 在里面找出唯一匹配的数据 否则验证失败。不同于数据库 openldap支持匿名访问。可以查询文档了解ldap 附上连接https://www.cnblogs.com/Actexpler-S/p/7819192.html
- ldap通过验证后只是通过了ldap的验证,svn也配置了权限,如果通过验证后 svn没有权限 但是没有相应的权限页面会提示没权限查看的。