基於目前最新的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, yum -y install 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將無法使用,慎之。
原本想將數據庫更改為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 的使用