背景:最近自己的omnifocus软件同步总有连接问题,查了下说明,发现omnifocus同步服务器可以被替换成其它支持webdav功能的服务器。看了看国内的webdav的服务,发现都要花钱。我这个人穷不拉几的不想再多一个续费项了。无巧不巧的我手头正好有个阿里云的CentOS系统。上面就跑着个GitLab用来给我存点无关紧要的东西。所以我决定试试自己搞一个webdav试试……嗯,这就是一切噩梦源头的开始……
在http服务上,我选择了nginx,没有去选用apache,主要是由于我以前在系统上部署过nginx。nginx想要支持webdav功能,需要在编译时添加扩展dav插件。所以需要自己下载nginx源码和dav组件源码再一起编译一个混血版。
名称 | 版本 | 下载链接 |
---|---|---|
nginx | 1.20.1 | https://nginx.org/en/download.html |
nginx-dav-ext-module | N/A | https://gitee.com/mirrors/nginx-dav-ext-module?_from=gitee_search https://github.com/arut/nginx-dav-ext-module |
两部分代码下载下来,nginx我下下来的是.tar.gz结尾的压缩格式,需要先解压
[root@AliS _Soft]# tar zxvf nginx-1.20.1.tar.gz
[root@AliS _Soft]# ls -ld nginx*
-rw-r--r-- 1 root root 981687 Jan 5 2018 nginx-1.12.2.tar.gz
drwxr-xr-x 9 sftpusers www 4096 Jul 10 10:43 nginx-1.20.1
-rw-r--r-- 1 root root 1061461 May 25 23:34 nginx-1.20.1.tar.gz
drwxr-xr-x 3 root root 4096 Jul 9 21:03 nginx-dav-ext-module
请忽略掉那个无知的nginx-1.12.2的文件……
由于我编译的nginx除了支持webdav,还需要支持我系统上原来的gitlab。gitlab在安装的时候自带一个内嵌的nginx,需要用我新编译的私有nginx替换掉,所以先查看一下gitlab内嵌的nginx带的参数
[root@AliS _Soft]# /opt/gitlab/embedded/sbin/nginx -V
nginx version: nginx/1.12.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2l 25 May 2017
TLS SNI support enabled
configure arguments: --prefix=/opt/gitlab/embedded --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_v2_module --with-http_realip_module --with-ipv6 --with-debug --with-ld-opt=-L/opt/gitlab/embedded/lib --with-cc-opt='-L/opt/gitlab/embedded/lib -I/opt/gitlab/embedded/include'
打开一个自己必须喜欢的文本文档工具,我用的VSCode,眉飞色舞的写下一个编译用的config。其实就是写个头儿和加个dav的参数,中间的参数大部分都是拷贝的gitlab里面的configure arguments的段……
./configure \
--prefix=/usr/local/nginx-1.20.1 \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_v2_module \
--with-http_realip_module \
--with-debug \
--with-ld-opt='-L /opt/gitlab/embedded/lib' \
--with-cc-opt='-L /opt/gitlab/embedded/lib -I /opt/gitlab/embedded/include' \
--with-http_dav_module --add-module='/root/_Soft/nginx-dav-ext-module/nginx-dav-ext-module'
参数 | 说明 |
---|---|
–prefix | 指定编译后的nginx目录。我指定了一个和gitlab的nginx不同的目录,这样万一玩砸了,至少我还有机会用老的nginx把我的gitlab服务拉起来,不会死的很惨。 |
–with-* | 都是一些nginx的模块,为了同时支持gitlab,我就原封不动的C/P了它的参数。 一定要把 --with-http_dav_module --add-module=’/root/_Soft/nginx-dav-ext-module/nginx-dav-ext-module’加进来,这个路径就是下的那个模块的存放路径 还有别问我为啥有两级nginx-dav-ext-module,git同步的,结果忘记它自己很聪明会自己建目录,搞技术太难了…… |
–add-module | 指定外部插件源代码的目录 |
\ | 这东西是一行写不下用来换行用的 |
之后就是进入到nginx源码目录去运行编译了。注意是nginx的源码目录,别进城nginx-dav的插件目录了
[root@AliS _Soft]# cd nginx-1.20.1
[root@AliS nginx-1.20.1]# ls
CHANGES CHANGES.ru LICENSE Makefile README auto conf configure contrib html man objs src
先配置一下要编译的内容,从你喜欢的文本工具中复制刚才已经写好的命令
[root@AliS nginx-1.20.1]# ./configure \
> --prefix=/usr/local/nginx-1.20.1 \
> --with-http_ssl_module \
> --with-http_stub_status_module \
> --with-http_gzip_static_module \
> --with-http_v2_module \
> --with-http_realip_module \
> --with-debug \
> --with-ld-opt='-L /opt/gitlab/embedded/lib' \
> --with-cc-opt='-L /opt/gitlab/embedded/lib -I /opt/gitlab/embedded/include' \
> --with-http_dav_module --add-module='/root/_Soft/nginx-dav-ext-module/nginx-dav-ext-module'
回车自己去敲吧,反正最后提示成功就是成功了。提示别的就是写错了……
之后就是编译了
[root@AliS nginx-1.20.1]# make & make install
后面就是等着编译log去刷屏了,刷完了就好了,不用搭理它。我说个小插曲轻松一下。
在我四处百度编译命令的时候,打开的第一个文章(利用Nginx WebDAV搭建自己的网盘),里面的编译命令是这么写的
# make -j8
我心说哥们你make就make吧,怎么还骂人呢!后来一查才知道,-j 是指定用多少个CPU core并行编译,可以增加编译速度的。丢人~
后来我还特意试了试用不同核数去编译,其实一个nginx用一个核也编译不了多会儿的,j8不j8的问题都不大嘿……
看完那段差不多编译也就结束了,一个属于自己的nginx应该已经静静的躺在你编译配置指定的目录里了(我的在/usr/local/nginx-1.20.1)
[root@AliS local]# ln -s nginx-1.20.1 nginx
[root@AliS local]# ls -ld nginx*
lrwxrwxrwx 1 root root 12 Jul 10 10:46 nginx -> nginx-1.20.1
drwxr-xr-x 11 root root 4096 Sep 29 2018 nginx-1.12.2
drwxr-xr-x 12 root root 4096 Jul 11 21:33 nginx-1.20.1
[root@AliS local]# pwd
/usr/local
[root@AliS local]#
为了图方便,我做了个nginx的软连接仍在相同的目录了,这样玩砸了回滚会简单点,只切换个软连接指向就好了,省的把目录内外搞得乌烟瘴气的
其实没有gitlab影响可以跳过这一章的,都去抽根烟吃个果盘儿歇会儿吧~
文件 | 说明 |
---|---|
/etc/gitlab/gitlab.rb | gitlab配置文件 |
/var/opt/gitlab/nginx/conf/ | gitlab内嵌nginx配置文件目录 |
/usr/local/nginx/conf | 私有nginx配置文件目录 |
/usr/local/nginx/conf/vhosts | 私有nginx vhosts配置目录 |
端口 | 端口定义 |
---|---|
8091 | 私有nginx提供的gitlab对外访问端口 |
8891 | 私有nginx提供的gitlab_workhorse内部访问端口 |
其实这步说难不难,主要是不要马虎大意。用vi或者喜欢的编辑器打开配置文件一顿脑残编辑就好了
另外,想着先拷贝一份当前的配置文件到别的目录做个备份,备份别放在/etc目录下就行。
先搞一下/etc/gitlab/gitlab.rb,这个是gitlab的配置文件,下面中的#是文件注释,我习惯于拷贝出来一行原参数再取消注释进行修改。
# external_url 'http://gitlab.example.com'
external_url 'http://50.50.50.50:8091' #改成自己gitlab的真实访问的地址就行
# nginx['enable'] = true
nginx['enable'] = false #关闭gitlab内置的nginx功能
# gitlab_workhorse['listen_network'] = "unix"
gitlab_workhorse['listen_network'] = "tcp" #更改workhorse的传输方式从socket到TCP
# gitlab_workhorse['listen_addr'] = "/var/opt/gitlab/gitlab-workhorse/socket"
gitlab_workhorse['listen_addr'] = "127.0.0.1:8891" #我设置了8891端口,其实找个别的没用的端口就行
# gitlab_rails['trusted_proxies'] = []
gitlab_rails['trusted_proxies'] = ['50.50.50.50'] #把gitlab的对外地址加到rail的信任列表里
# web_server['external_users'] = []
web_server['external_users'] = ['root', 'nobody'] #我一劳永逸的都加进去了
编辑完gitlab.rb文件,还需要把gitlab原先内嵌的nginx提供的服务添加到自己私有的nginx里面
[root@AliS ~]# cd /var/opt/gitlab/nginx/conf/
[root@AliS conf]# ls
gitlab-http.conf nginx-status.conf nginx.conf
上面是我的gitlab内嵌nginx放配置的地方,nginx.conf是主配置文件,其他两个都在nginx.conf中被引用了,所以本着能懒就懒的原则,我决定回头把nginx.conf的内容合并到我的私有nginx配置里就好,引用的那两个文件就还放在这里不动了。
传说中nginx可以使用vhosts功能分离配置文件,为了简便,我直接把gitlab的内容拷贝成一个vhosts配置文件,依旧防止我手残的把主配置文件修改的乱七八糟
先在私有的nginx conf目录建一个vhosts的文件夹
[root@AliS conf]# pwd
/usr/local/nginx/conf
[root@AliS conf]# mkdir vhosts
然后在conf目录修改nginx.conf文件,添加要引用vhosts目录的文件
user root gitlab-www;
...
http {
...
include vhosts/*.conf;
}
修改ngnix.conf的时候,要看一下开头的user定义,是用的哪个用户来假装运行nginx的,这个用户要包含在gitlab.rb的下列配置中(我是用的root啦)
web_server[‘external_users’] = [‘root’, ‘nobody’]
之后我就是在vhosts目录新建了一个gitlab.conf,再大刀阔斧的把gitlab里面的nginx配置拷贝了过来。拷贝过来后要注意两点
server {
listen 8091;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_pass http://127.0.0.1:8891;
}
}
这里定义的8091端口,是对外访问gitlab的地址,之后获得的数据会被转发给http://127.0.0.1:8891。所以这个8891的端口要和gitlab.rb中修改的配置一致,不然gitlab_workhorse就接收不到数据了,页面也会报告很难搞得504 error……(别问我怎么知道的,8091,8891,8091,8891当初定义的太像了,加上我眼睛又近视,这个错误白白浪费了我5根烟!)
gitlab_workhorse[‘listen_addr’] = “127.0.0.1:8891”
下面上整个配置文件
# gitlab config
# The orignal git lab nginx is /opt/gitlab/embedded/sbin/nginx -p /var/opt/gitlab/nginx
log_format gitlab_access '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent"';
log_format gitlab_mattermost_access '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent"';
server_names_hash_bucket_size 64;
# sendfile on;
tcp_nopush on;
tcp_nodelay on;
# keepalive_timeout 65;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json;
# include /opt/gitlab/embedded/conf/mime.types;
proxy_cache_path proxy_cache keys_zone=gitlab:10m max_size=1g levels=1:2;
proxy_cache gitlab;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Remove private_token from the request URI
# In: /foo?private_token=unfiltered&authenticity_token=unfiltered&rss_token=unfiltered&...
# Out: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
map $request_uri $temp_request_uri_1 {
default $request_uri;
~(?i)^(?<start>.*)(?<temp>[\?&]private[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
}
# Remove authenticity_token from the request URI
# In: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
map $temp_request_uri_1 $temp_request_uri_2 {
default $temp_request_uri_1;
~(?i)^(?<start>.*)(?<temp>[\?&]authenticity[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
}
# Remove rss_token from the request URI
# In: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=[FILTERED]&...
map $temp_request_uri_2 $filtered_request_uri {
default $temp_request_uri_2;
~(?i)^(?<start>.*)(?<temp>[\?&]rss[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
}
# A version of the referer without the query string
map $http_referer $filtered_http_referer {
default $http_referer;
~^(?<temp>.*)\? $temp;
}
server {
listen 8091;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_pass http://127.0.0.1:8891;
}
}
include /var/opt/gitlab/nginx/conf/gitlab-http.conf;
include /var/opt/gitlab/nginx/conf/nginx-status.conf;
一切顺利的话,现在就可以kill掉gitlab内嵌的nginx,并且启动自己私有的nginx了
[root@AliS ~]# /usr/local/nginx/sbin/nginx
如果幸运的话,你可以快乐的用ps -ef|grep nginx看到你的nginx在快乐的奔跑,但是显然,我不太幸运。我运行的时候,系统残酷的提示我
nginx: error while loading shared libraries: xxxx.so
这个时候,可以使用一个叫做ldd的命令去看,导致都有哪些库没找到。如果没找到,会在对应的库文件下写not found。这个时候,去看看gitlab内嵌的nginx的库文件在哪,做个软链接到/lib64下就好了。
下面给大家看看ldd的输出,我的因为写文章之前已经做过软链接了,所以就看不到报错了
[root@AliS ~]# ldd /usr/local/nginx/sbin/nginx
linux-vdso.so.1 => (0x00007ffc3bbd6000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f6fc1446000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6fc122a000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f6fc0ff2000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f6fc0d90000)
libssl.so.1.0.0 => /lib64/libssl.so.1.0.0 (0x00007f6fc0b1e000)
libcrypto.so.1.0.0 => /lib64/libcrypto.so.1.0.0 (0x00007f6fc06d0000)
libz.so.1 => /lib64/libz.so.1 (0x00007f6fc04ba000)
libxml2.so.2 => /lib64/libxml2.so.2 (0x00007f6fc0150000)
libxslt.so.1 => /lib64/libxslt.so.1 (0x00007f6fbff10000)
libexslt.so.0 => /lib64/libexslt.so.0 (0x00007f6fbfcfb000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6fbf938000)
/lib64/ld-linux-x86-64.so.2 (0x000055ad92e0a000)
libfreebl3.so => /lib64/libfreebl3.so (0x00007f6fbf734000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f6fbf50e000)
libm.so.6 => /lib64/libm.so.6 (0x00007f6fbf20c000)
libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007f6fbef8a000)
libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f6fbed85000)
[root@AliS ~]#
之后就是让gitlab配置生效了
[root@AliS ~]# gitlab-ctl reconfigure
[root@AliS ~]# gitlab-ctl restart
gitlab提供了一个简单的命令把相关的log打印在一起,如果里面没有报错就没啥问题了。
[root@AliS ~]# gitlab-ctl tail
最后就是测试一下,打开一个浏览器输入gitlab的地址,看看能不能正常访问了(虽然只是简单的一句话,但是为了实现这句话花费了我一包烟的时间)
端口 | 端口定义 |
---|---|
8094 | 私有nginx提供的webdav对外访问端口 |
那些没在系统上部署过gitlab的烟民可以回来了
私有nginx运行正常后,配置webdav的过程就比较简单了
给webdav建个带目录不能直接登录的组和用户,然后再在webdav的home目录建立个用来存放数据的目录,我的是/home/webdav/data
下面这堆命令都是新建用户的固定搭配
[root@AliS home]# groupadd webdav
[root@AliS home]# useradd -d /home/webdav -g webdav -s /sbin/nologin webdav
[root@AliS home]# cd webdav
[root@AliS webdav]# mkdir data
[root@AliS webdav]# ls
data
[root@AliS webdav]# pwd
/home/webdav
[root@AliS webdav]# chown webdav:webdav data
[root@AliS webdav]# ls -l
total 4
drwxr-xr-x 2 webdav webdav 4096 Jul 11 21:30 data
之后回到私有nginx的conf目录,给webdav建立一个用户存放用户名密码的shadow文件
echo 用户名:$(openssl passwd -crypt 密码)>/etc/nginx/webdavpasswd
[root@AliS nginx]# mkdir webdav
[root@AliS nginx]# echo omniuser:$(openssl passwd -crypt omnipassword)>/usr/local/nginx/webdav/webdavpasswd
在/usr/local/nginx/conf/vhosts下添加一个vhosts的配置文件,我的是webdav.conf
文件内容如下
server {
server_name localhost;
listen 8094;
location / {
set $dest $http_destination;
if (-d $request_filename) {
rewrite ^(.*[^/])$ $1/;
set $dest $dest/;
}
if ($request_method ~ MKCOL) {
rewrite ^(.*[^/])$ $1/ break;
}
root /home/webdav/data;
autoindex on;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
create_full_put_path on;
client_max_body_size 0M;
dav_access user:rw group:rw all:rw;
auth_basic "Authorized Users Only";
auth_basic_user_file /usr/local/nginx/webdav/webdavpasswd;
}
}
最后让nginx重新加载下配置文件,基本配置就完成了
[root@AliS webdav]# /usr/local/nginx/sbin/nginx -s reload
后面测试一下,我的linux是没有装davfs的,所以要想在本机测试,要先让系统支持davfs的mount
[root@AliS mnt]# yum search davfs
Failed to set locale, defaulting to C
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
===================================================================== N/S matched: davfs =====================================================================
davfs2.x86_64 : A filesystem driver for WebDAV
Name and summary matches only, use "search all" for everything.
[root@AliS mnt]#
[root@AliS mnt]# yum install -y davfs2.x86_64
Failed to set locale, defaulting to C
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package davfs2.x86_64 0:1.4.7-6.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
==============================================================================================================================================================
Package Arch Version Repository Size
==============================================================================================================================================================
Installing:
davfs2 x86_64 1.4.7-6.el7 epel 148 k
Transaction Summary
==============================================================================================================================================================
Install 1 Package
Total download size: 148 k
Installed size: 341 k
Downloading packages:
davfs2-1.4.7-6.el7.x86_64.rpm | 148 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : davfs2-1.4.7-6.el7.x86_64 1/1
Verifying : davfs2-1.4.7-6.el7.x86_64 1/1
Installed:
davfs2.x86_64 0:1.4.7-6.el7
Complete!
装好啦,改改配置,我也把use_locks改成了0
[root@AliS mnt]# vi /etc/davfs2/davfs2.conf
mount一下试试,能挂载上就是做好了
[root@AliS mnt]# mkdir webdav
[root@AliS mnt]# mount -t davfs http://50.50.50.50:8094 /mnt/webdav
Please enter the username to authenticate with server
http://50.50.50.50:8094 or hit enter for none.
Username: omni
Please enter the password to authenticate user webdav with server
http://50.50.50.50:8094 or hit enter for none.
Password:
/sbin/mount.davfs: Warning: can't write entry into mtab, but will mount the file system anyway
[root@AliS mnt]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 29G 8.5G 78% /
devtmpfs 7.8G 0 7.8G 0% /dev
tmpfs 7.8G 4.0K 7.8G 1% /dev/shm
tmpfs 7.8G 480K 7.8G 1% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
tmpfs 1.6G 0 1.6G 0% /run/user/0
http://50.50.50.50:8094 26G 13G 13G 50% /mnt/webdav
[root@AliS mnt]# ls
webdav
[root@AliS mnt]# cd webdav/
[root@AliS webdav]# ls
lost+found
当然,上面我删除了一部分信息。我自然没有文章中写的这么顺利,现实和理论总是有差距的,我一直都是下列错误
[root@AliS mnt]# mount -t davfs http://http://50.50.50.50:8094 /mnt/webdav
mount: unknown filesystem type 'davfs'
[root@AliS mnt]# mount -t davfs http://http://50.50.50.50:8094 /mnt/webdav
/sbin/mount.davfs: invalid URL
[root@AliS mnt]# mount -t davfs http://50.50.50.50:8094 /mnt/webdav
Please enter the username to authenticate with server
http://50.50.50.50:8094 or hit enter for none.
Username: webdav
Please enter the password to authenticate user webdav with server
http://50.50.50.50:8094 or hit enter for none.
Password:
/sbin/mount.davfs: connection timed out two times;
一切准备妥当,软件这边的设置就异常简单了
只要在omnifocus的设置/同步功能里面,把对应的webdav的服务器地址(http://50.50.50.50:8094)连带端口号填好,输入用户名密码就好了。唯一需要注意的是,用于同步的第一个设备的数据,将成为服务器上的原始数据库,之后这个数据会覆盖其他后加入同步的设备。小心不要用错误数据覆盖正确数据就好了。
最后多谢写这些文章的大神们