在服务器上搭建工作环境

基于目前最新的CentOS-7-x86_64-Minimal-1804。


FTP

使用vsftpd搭建ftp服务。网上关于vsftpd如何配置的文章很多,各抒己见且各自凌乱,本文意图简明阐述该过程。

 yum install -y vsftpd 自动安装,很快完成,版本3.0.2。

vsftpd支持三类用户登录

  • 匿名用户
  • 本地用户(os账号如root)
  • 虚拟用户(非os账号但vsftpd可识别,一般以这种账号为多,方便管理且权限局限于ftp范围)

需注意,所有虚拟账户需要映射到同一个本地账户,因为毕竟读写文件等操作最终是由本地账户负责的,只是vsftpd会在处理连接时根据发起请求的虚拟账户的相关配置来做一些额外控制,比如虚拟账户可操作的目录权限等,相关配置在后面会讲到。

so,我们新建一个本地账户 useradd -s /sbin/nologin ftpvuser ,/sbin/nologin表示该账号不能直接登录系统,此处它只是给vsftpd操作文件使用。我们可以在自动生成的/home/ftpvuser目录下建需要的子目录,比如我为公司各部门建了对应目录 mkdir hr adm prd dev opra finance ,之后创建的虚拟账户就会配置相应目录的权限。

存储虚拟账户有两种方式,一种文件方式,一种数据库,简单起见,我使用文本文件的方式。格式很简单,一行用户名一行密码,奇数行为用户名,偶数行为密码。我们还需要使用db_load 命令将其生成db, db_load -T -t hash -f vuser_list vuser.db ,其中选项-T允许应用程序能够将文本文件转译载入进数据库,-t hash使用hash码加密,-f 指定包含用户名和密码文本文件,格式要求如前所述。

vsftpd使用pam机制认证用户。Linux-PAM(linux可插入认证模块)是一套共享库,可以按需要动态的对验证的内容进行变更,大大提高验证的灵活性,可参看 Linux下PAM模块学习总结 。个人理解应用程序只要负责提供用户信息,如何认证则交由pam完成,当然认证逻辑需要我们组织pam文件。在/etc/pam.d目录下新建ftpvuserlogin文件,并在其中写入

auth required pam_userdb.so db=/etc/vsftpd/vuser
account required pam_userdb.so db=/etc/vsftpd/vuser

其中/etc/vsftpd/vuser就是我们之前生成的db文件。

编辑/etc/vsftpd/vsftpd.conf文件

 1 anonymous_enable=NO    # 修改,禁止匿名用户登录
 2 local_enable=YES    # 默认启用,允许本地用户登录,虚拟用户需要映射到本地用户才可以使用
 3 
 4 # 虚拟用户配置项
 5 guest_enable=YES    # 增加,启用虚拟用户模式
 6 guest_username=ftpvuser    # 增加,配置虚拟用户映射到的本地用户名
 7 pam_service_name=ftpvuserlogin    # pam配置文件
 8 user_config_dir=/etc/vsftpd/vuser_cfg    # 增加,虚拟用户的配置文件目录
 9 anon_umask=022    # 增加,匿名用户新增文件的umask数值。默认值为077
10 
11 # 根目录配置,用户登录后进入的目录
12 local_root=/home/ftpvuser
13 anon_root=/home/ftpvuser
14 
15 # 打开被动模式
16 pasv_enable=YES
17 pasv_min_port=9000
18 pasv_max_port=9999

有几行内容我们暂时没接触到,现下一个个来看。

第8行表示每个虚拟用户自个的配置文件存放的目录。每个用户各自对应一个同名文件,如a用户的配置文件名就是a,各配置项大概如下:

 write_enable=YES
 local_root=/home/ftpvuser    # 登录后进入目录
 anon_upload_enable=YES    # 上传
 anon_mkdir_write_enable=YES    # 创建目录写权限
 anon_other_write_enable=YES    # 其他写入权限
 anon_world_readable_only=YES

anon开头的不是很明白,大家可以设置不同值看看效果。我改动local_root到别的目录,目录权限已设置为映射的本地账号,无法登录,不知为何。需要设置virtual_use_local_privs=YES,表示虚拟用户的权限与他们的宿主用户保持一致。

第9行anon_umask表示创建的文件/目录的权限。umask是unix操作系统的概念,umask决定目录和文件被创建时得到的初始权限。umask = 022 时,新建的目录权限是755,文件的权限是644;umask = 077 时,新建的目录权限是700,文件的权限是600。vsftpd的local_umask和anon_umask借鉴了它。默认local_umask=022,anon_umask=077,我登录了虚拟账户,新建的目录权限一直是700,然后我在新建的目录下再建子目录就抛出550错误。后来我设置了anon_umask=022,就没问题了。所以说虚拟账户虽然映射了本地账户,但是配置项还是以anon_为准?若是,则可以解释针对每个虚拟用户的配置文件里面怎么那么多anon开头的配置项了,同时也解释了为啥700不能写入而755可以写入。

第16-18行是开启了FTP被动模式,并设置数据端口范围。FTP有两种模式,PORT(主动)模式,PASV(被动)模式,vsftpd默认开启主动模式,然而一些ftp客户端(如winscp、windows文件浏览器)并不支持,登录时会抛出“425 failed to establish connection”错误,所以我们要另外开启被动模式。关于两种模式,可参看 vsftpd的主动模式与被动模式

不出意外,现在就可以使用虚拟用户名密码远程登录FTP了,然而登录上去之后只能进入到设置好的对应目录中(通过用户配置文件local_root设置)。假如我们要给用户a赋予/home/ftpvuser/dev目录读写权限,同时还能让他看到/home/ftpvuser/prd目录下的内容,该如何是好。首先先将其local_root=/home/ftpvuser/dev,然后在dev目录下新建一个prd子目录(名字随便取),/home/ftpvuser/prd考虑用软硬连接链过来,然而硬链接不支持目录,vsftpd又不支持软连接。可以使用mount --bind将目录挂载过来,同时考虑到挂载目录只有源目录的只读模式,so  mount -o rbind,ro /home/ftpvuser/prd /home/ftpvuser/dev/prd 完成(man mount展示的mount --rbind,ro用法有误,unrecognized option)。最好写入/etc/rc.local以便重启后挂载关系仍在(需run 'chmod +x /etc/rc.d/rc.local')。


Docker部署私有云

上节可见,ftp的配置繁琐,且不灵活,管理员要肩负起账号的管理,每个账号对目录的权限控制也很麻烦且不一定能达到要求,另用户也无法直接在ftp上移动文件或目录,只能先下载再上传到不同地方。目前,我们可以考虑使用开源的私有云(seafile/owncloud/nextcloud等)代替。

考虑使用docker将该应用与宿主环境隔离。

安装docker,参看CentOS 8.0安装Docker

nextcloud

# 查看nextcloud镜像
docker search nextcloud
# pull官方镜像
docker pull docker.io/nextcloud
# 运行容器
# --restart=always,docker环境启动后容器跟着启动
# 其它选项参看后面部署禅道小节
# 容器目录(如/var/www/html/data)可参看官方说明
# https://hub.docker.com/_/nextcloud
docker run -d --restart=always --name nextcloud -p 8092:80 -v /home/ftpvuser:/var/www/html/data docker.io/nextcloud

此时便可浏览 http://192.168.10.120:8090/ 进行相关配置。注意我在run的时候将之前的ftp目录挂载到了容器的/var/www/html/data,run之后,ftp目录的owner将变为extcloud创建的一个www-data用户,so,按上节配置的vsftpd将无法使用,慎之。

-v 表示将宿主机目录/文件 映射到容器对应的目录/文件,注意宿主机目录将覆盖容器目录。

原本想将数据库更改为mysql,信息填完点完成,弹出提示:The server requested authentication method unknown to the client。由于我数据库装的是mysql8,默认使用caching_sha2_password作为身份验证插件,应该是该容器还不支持,so登录mysql,增加一个使用mysql_native_password验证的用户, CREATE USER '<username>'@'%' IDENTIFIED WITH mysql_native_password BY '<password>'; 。结果又提示“Access denied for user 'oc_xxx'@'172.17.0.3' (using password: YES) ”,貌似nextcloud自动创建了一个数据库用户oc_xxx(xxx为安装界面输入的云管理员用户名),不知为何,若将所有权限赋予oc_xxx,则又会另创建了许多oc_xxx1、2、3用户,且都提示权限不足。查看https://docs.nextcloud.com/server/14/admin_manual/configuration_database/linux_database_configuration.html,寻找蛛丝马迹,感觉有点复杂,遂放弃。

seafile(6.x版)

nextcloud不支持群组共享,so考虑用seafile,只是seafile会将上传的文件分块处理,所以我们不能直接在服务器端将原有文件拷贝到seafile目录下。不过seafile专业版支持将服务器上的一个本地文件目录导入到seafile中;开源版的话貌似只能重新上传了。

docker run -d --name seafile -e SEAFILE_ADMIN_EMAIL=gttx@gttx.com -v /home/seafile-data:/shared -p 8091:80 -p 8000:8000 -p 8082:8082 docker.io/seafileltd/seafile

注意,需要将/opt/seafile/conf下的seahub_settings.pyc的默认域名example.seafile.com改为局域网IP:PORT,否则无法上传文件。


Git

暂不考虑web管理等高级功能,所以未采用GitWeb或Gitlab,而是使用git本身搭建基础服务。

yum install git之前先 yum info git,发现yum库里的版本是1.8.3.1,忒低,于是编译装。

1 //依赖库安装
2 yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel 
3 yum install gcc perl-ExtUtils-MakeMaker 
4 //卸载低版本的 Git 
5 yum remove git 
6 //下载新版的 Git 源码包
7 wget https://github.com/git/git/archive/v2.19.2.tar.gz
8 tar -xzvf v2.19.2.tar.gz

第2行很多xxx-devel命名的包,这些包是其它库引用于开发相关功能。如Redhat在封装openssl的时候,把openssl分成了几个部分,执行码部分就是 openssl-1.0.0-27.el6.x86_64 这种包;openssl-devel-1.0.0-27.el6.x86_64 这个就是包含了头文件,头文件参考,某些库文件等跟开发相关的东西。

编译安装

cd git-2.19.2
make prefix=/usr/local/git all
make prefix=/usr/local/git install

在命令行输入make命令后,会查找当前目录下的Makefile文件来执行,一切都是自动运行的。有时候Makefile中有多个程序需要编译,这时可以使用“make all”来编译所有的程序。当然也可以使用“make 程序名”来单独编译某一个文件。make install 功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。

添加到环境变量,在/etc/profile中添加 export PATH="/usr/local/git/bin:$PATH",然后 source /etc/profile 使配置立即生效。

新增git用户

$ groupadd git
$ adduser git -g git

修改/etc/passwd文件,禁止git登录,找到git:x:503:503::/home/git:/bin/bash,改为git:x:503:503::/home/git:/usr/local/git/bin/git-shell,其中/usr/local/git是你的git安装目录。我就是因为这个路径没配对,导致每次连接git都要让我输密码,最后查看/var/log/secure才发现是git-shell没找到的缘故。

开启RSA认证,打开/etc/ssh/sshd_config,配置

RSAAuthentication yes
PubkeyAuthentication yes

在其中我们能看到配置项AuthorizedKeysFile .ssh/authorized_keys,表示git客户端的公钥都放置在.ssh/authorized_keys中,格式为一行一个。所以我们在git的家目录下创建.ssh/authorized_keys(注意git目录下所有子目录或文件都需要给git赋予rwx权限)。

客户端生成密钥对

第一步: 创建客户端的ssh私钥和公钥
检查是否已经拥有ssh公钥和私钥:进入用户的主目录。
用户主目录:
Windows系统:C:\Users\用户名
Linux系统:/home/用户名
Mac系统:/Users/用户名
然后查看是否有.ssh文件夹,此文件夹下是否有id_rsa(私钥)和id_rsa.pub(公钥),若无则使用ssh-keygen创建。将id_rsa.pub拷到服务器,并cat至之前创建的/home/git/.ssh/authorized_keys上。

使用ssh-add命令将私钥加入本机ssh-agent中,否则每次连接都要带上私钥。

服务端开启ssh需要的22端口,并git init一个空仓库,不出意外,客户端应该可以进行clone或者remote add此仓库了。

参考资料:Centos7搭建git服务器端


Docker部署禅道

hub.docker.com,搜php,会出来一坨镜像,apache+php是标配,另考虑到可能的调试需求,我们选择webdevops/php-apache-dev, docker pull webdevops/php-apache-dev 。关于该镜像的说明可以进https://dockerfile.readthedocs.io/en/latest/content/DockerImages/dockerfiles/php-apache-dev.html查看,文档中对各tag和镜像文件有说明。默认下载的是latest。

# -d 启动后后台运行
# --name 指定容器名称,单台宿主机中,容器名称须唯一
# -p 端口映射,宿主端口:容器端口(apache默认端口80)
# -v 目录映射,宿主目录:容器目录,若不存在会自动创建;可同时定义多个映射
# 最后那个字符串是镜像ID
docker run -d --name apachephp -p 8090:80 -v /home/websites:/var/www/html 47b0d3d278c1

容器启动后,有两种方法可以进入容器。

# 交互模式
docker exec -it apachephp /bin/bash
# 非交互模式
docker attach apachephp

我们可以在宿主机目录/home/websites,或者容器目录/var/www/html下新建一个index.php(不管哪里建,两边都能访问到)。

开放端口,然后浏览器浏览192.168.xx.xx:8090/index.php,报404。查看容器内的opt/docker/etc/httpd/conf.d/10-server.conf(注意并非网上所说httpd.conf),发现DocumentRoot为"/app",而非启动时映射的/var/www/html。so,我们再起一个容器试试。

docker run -d --name phpapache -p 8091:80 -v /home/websites:/app 47b0d3d278c1

由于我们之前已经在宿主机的/home/websites下有了index.php,所以现在可以直接浏览192.168.xx.xx:8091/index.php,妥妥的没问题。

同一镜像起多个容器,系统会对每个容器创建新进程,虽然容器共享kernel和镜像数据,但每个进程各自维护完整的应用运行环境,这会不会导致性能(cpu/内存)问题呢?试想有100个微服务,就有100个IIS进程的恐怖场景吧。

部署禅道(10.6版本)

去官网下压缩包,放到/home/websites下面,解压后,浏览器输入192.168.xx.xx:8090/zentaopms/www/开始安装。安装前我担心由于mysql是直接安装在宿主机上,可能会导致无法通信的情况,结果宿主机与容器可以相互ping通,多虑了。

error:您访问的域名没有对应的公司。解决方法:进入容器,新建一个目录(如/app/sessionrep),找到/opt/docker/etc/php/php.ini,在里面加一行session.save_path = "/app/sessionrep",把zentaopms/config/my.php删了,然后重启apache,重新安装即可。注意将/app/sessionrep的写权限赋给所有用户,避免服务器重启后用户无法登录禅道。

使用:全流程的话,应该是创建产品线——创建产品——新增需求——需求评审后激活[——创建计划]——创建项目——关联需求——分解任务——……


其它

Linux中,若用户无父目录的x(打开)权限,则就算子目录有rwx权限,亦无法进入到子目录。

在 linux 或者 unix 系统中, 都可以通过编辑 bashrc 和 profile来设置用户的工作环境,相关文件/etc/profile、/etc/bashrc、~/.bashrc、~/.profile,前两者系统级,后两者当前用户级。profile 是某个用户唯一的用来设置环境变量的地方, 因为用户可以有多个 shell 比如 bash, sh, zsh 之类的, 但像环境变量这种其实只需要在统一的一个地方初始化就可以了, 而这就是 profile;bashrc是专门用来给 bash 做初始化的比如用来初始化 bash 的设置, bash 的代码补全, bash 的别名, bash 的颜色. 以此类推也就还会有 shrc, zshrc 这样的文件存在了, 只是 bash 太常用了而已。详细可参看 /etc/bashrc和/etc/profile傻傻分不清楚?

ssh远程连接服务器慢(包括登录、git clone等),可以使用ssh -v xxx@host查看慢在哪一步。一般来说进入/etc/ssh/sshd_config,将UseDNS和GSSAPIAuthentication都设置为no,并systemctl restart sshd.service重启sshd进程使配置生效即能解决。

软连接和硬连接

硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。比如:A是B的硬链接(A和B都是文件名),则A的目录项中的inode节点号与B的目录项中的inode节点号相同,即一个inode节点对应两个不同的文件名,两个文件名指向同一个文件,A和B对文件系统来说是完全平等的。删除其中任何一个都不会影响另外一个的访问。
另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。比如:A是B的软链接(A和B都是文件名),A的目录项中的inode节点号与B的目录项中的inode节点号不相同,A和B指向的是两个不同的inode,继而指向两块不同的数据块。但是A的数据块中存放的只是B的路径名(可以根据这个找到B的目录项)。A和B之间是“主从”关系,如果B被删除了,A仍然存在(因为两个是不同的文件),但指向的是一个无效的链接。

centos7终端支持中文:单修改/etc/locale.conf起不了作用,需再修改/etc/profile.d/lang.sh,参看 修改CentOS7,修改默认语言环境,解决中文乱码问题。

git merge 和 git rebase

这两个命令都可以用来合并分支,且最终结果相同,但是合并历史却不同;git merge是将两个分支做一个三方合并(如果不是直接上游分支),这样一来,查看提交历史记录,可能会显得非常凌乱。git rebase则会将当前分支相对于基低分支的所有提交生成一系列补丁,然后放到基底分支的顶端,从而使得提交记录变称一条直线,非常整洁,如下:

# 当前提交状态如下
#       A---B---C topic
#      /
# D---E---F---G master

# 执行
$ git rebase master topic

# 提交状态变为
#               A'--B'--C' topic
#              /
# D---E---F---G master

# 不是按两分支时间穿插排序,避免了提交历史错乱的情况

可参看 [Git] Git整理(四) git rebase 的使用

 

转载请注明本文出处:https://www.cnblogs.com/newton/p/10028689.html

posted @ 2018-11-28 15:21  莱布尼茨  阅读(2600)  评论(0编辑  收藏  举报