跳转至

RC 网络仓库服务介绍

Intro 服务是什么

本文档介绍的对象是一组部署在服务器上,用于RC视觉组共享与传承工作成果的Web服务。主要提供了私有远程git仓库服务(gogs),文档与博客分享服务(hugo),与文件下载服务,并最终通过 nginx (读作 Engine X) 集成到服务器的一个端口上。目前,该服务仅通过端口转发的形式,将运行在ROBOCON局域网下的服务器服务端口借由路由器(校园网域)暴露到一个校园网ip,每次路由器重启,校园网中的服务ip都会变化。

Aim 部署目的

  • 私有远程git仓库服务(以下以 git-service 代称):核心目的是用于收集视觉组各年工作项目,防止之前的方案随时间丢失。由于github,gitcode等网站的“组织”功能往往需要按时间付费,并且具有人数限制,因此采用 gogs 作为队内专用的git仓库。这个服务能够帮助团队协作开发(需要有git使用能力),跟踪各个组员进度。
  • 文档与博客分享(以下以 doc-service 代称):鼓励记录分享自己的经验,以及阅读他人的经验。采用 Docs 这一仓库,其可以将简单的markdown 文档生成美观的静态网站。
  • 文件下载服务(以下以 file-service 代称):除了保存资源文件,还可以把配置好的系统镜像,docker镜像放在里面,这样就可以免去配置环境的烦恼。现在采用的FileBrowser是一个充满bug的程序,打算换其他的。

Description 详细介绍

ssh 登录

从队里华为路由器登录界面(华为路由器默认局域网ip为192.168.3.1)可以看到,通过有线方式连接的 rc-server 记录其 ip 地址,可以在连接 ROBOCON 局域网的情况下访问服务器。主用户用户名是robocon,密码是qingchun,服务均部署在git用户下,git用户无法直接通过ssh登录,需要登录后切换。ssh 端口经过路由器转发到 22 端口,为了防止枚举用户名与密码破解,通过端口转发方式访问的连接都只能通过 public-key 方式进行登录认证,而无法使用密码登录。使用robocon和git用户登录服务器均需要公钥。

另外,如果您想从校园网登上服务器,您可以在局域网条件下先查看路由器在校园网下的WAN IP,然后通过该IP登录服务器。

1
2
# 从robocon用户切换到git用户
su git

git-service

SOURCE:

下载安装与首次配置

按照 中文文档 中的 下载安装-环境要求 配置依赖后,按照 下载安装-二进制安装/源码安装/包管理安装 中的任意一种方式进行安装(推荐使用压缩包安装),然后使用命令行运行"./gogs web"(压缩包安装),第一次启动服务,会在http://localhost:3000/install上启动配置安装界面,类似如下:

1754543311191

修改配置文件

请参照 下载安装-配置与运行配置文件中文解释 修改custom/conf/app.ini 的部分值。

目前部署在服务器上的配置文件如下,甚至密码都告诉你了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
BRAND_NAME = rc-Gogs
RUN_USER   = git
RUN_MODE   = prod

[database]
TYPE     = mysql
HOST     = 127.0.0.1:3306
NAME     = gogs
SCHEMA   = public
USER     = git
PASSWORD = qingchun
SSL_MODE = disable
PATH     = /home/git/gogs/data/gogs.db

[repository]
ROOT           = /home/git/gogs-repositories
DEFAULT_BRANCH = master
DISABLE_HTTP_GIT = true

[server]
DOMAIN           = rcserver
HTTP_ADDR        = 0.0.0.0
HTTP_PORT        = 5200
EXTERNAL_URL     = https://rcserver:5200/gogs/
DISABLE_SSH      = false
START_SSH_SERVER = false
PROTOCOL         = https
SSH_PORT         = 22
START_SSH_SERVER = false
OFFLINE_MODE     = true
CERT_FILE        = /home/git/cert/server/server.crt.pem
KEY_FILE         = /home/git/cert/server/server.key.pem 

[mailer]
ENABLED = false

[auth]
REQUIRE_EMAIL_CONFIRMATION  = false
DISABLE_REGISTRATION        = false
ENABLE_REGISTRATION_CAPTCHA = true
REQUIRE_SIGNIN_VIEW         = false

[user]
ENABLE_EMAIL_NOTIFICATION = false

[picture]
DISABLE_GRAVATAR        = false
ENABLE_FEDERATED_AVATAR = false

[session]
PROVIDER = file

[log]
MODE      = console,file
LEVEL     = Info
ROOT_PATH = /home/git/gogs/log

[security]
INSTALL_LOCK = true
SECRET_KEY   = OVfLU6Z3xEz1A16

配置开机启动服务

开机启动脚本均放置在 github-url中,对应到服务器上的路径则是/home/git/gogs/scripts/mygogs.service以 systemd 启动方式为例,具体结合两个中文教程的对应章节执行。已经实现的service脚本名称应该是 mygogs.service,直接修改该文件即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[Unit]
Description=Gogs
After=network.target
After=mysql.service mysqld.service

[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
Type=simple
User=git
Group=git
WorkingDirectory=/home/git/gogs
ExecStart=/home/git/gogs/gogs web
Restart=always
RestartSec=2s
Environment=USER=git HOME=/home/git

# Some distributions may not support these hardening directives. If you cannot start the service due
# to an unknown option, comment out the ones not supported by your version of systemd.
ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

使用nginx反向代理

当然,反向代理也可以统一用apache实现。注意,在 ubuntu 上开启 nginx 服务前,需要检查是否有 apache 抢占了80与443端口,如有需关。

具体部署时,服务器利用了nginx实现了一些高级功能。因此,如果想要对具体实现原理有所了解的话,便不能不了解nginx配置文件规则。

这一段代码将 /gogs/ location 下的所有服务重写到本地回环ip上

根据访问源ip判断是否是来自于ROBOCON局域网ip(通过ip是否是192.168.3.xxx来判断),如果是,则说明其是通过路由器内部访问的,允许访问注册界面,如果不是,则将对注册界面的访问重定向/重写到拒绝注册页面。

目前在/etc/nginx/sites-available/default中是这样配置的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

server{
    listen 80;
      # 你的域名或 IP 地址
    return 301 https://$host$request_uri;
}

geo $gogs_signup_disabled_ip {
    default 1;
    192.168.3.0/24 0;
}

server {
    listen 443 ssl;
    # 115.154.175.254:5200
    server_name _;  # 域名或 IP 地址

    ssl_certificate /home/git/cert/server/server.crt.pem;   # 证书路径
    ssl_certificate_key /home/git/cert/server/server.key.pem;  # 密钥路径

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'AESGCM:CHACHA20:!aNULL:!MD5:!3DES';
    ssl_prefer_server_ciphers off;

    error_page 497 301 =307 https://$host:5200$request_uri;
    location /register-denied.html {
        root /home/git/gogs/public/error_pages;
    }
    location = /gogs {
    rewrite ^/(.*) https://$host:5200/gogs/ break;
    }
    location ^~ /gogs/ {
    set $flag 0;
    if ($gogs_signup_disabled_ip) {
         set $flag "${flag}1";
        }
    if ($uri ~ ^/gogs/user/sign_up) {
        set $flag "${flag}2";
    }
    if ($flag = "012"){
        rewrite ^/(.*) https://$host:5200/register-denied.html break;
    }
        proxy_pass https://localhost:5200/;  # 代理到你的 HTTP 服务
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    location = /docsy {
    rewrite ^/(.*) https://$host:5200/docsy/ break;
    }
    location ^~ /docsy/ {
        alias /home/git/hugo/xjrcBlog/public/;
        index index.html;
    }
    location ^~ /files {

     rewrite ^/(.*) https://$host:5200/files/ break;
    }
    location ^~ /files/{
    proxy_pass http://localhost:5202/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
    alias /home/git/hugo/xjrcBlog/public/;
    index index.html;
    }
}

doc-service

SOURCE:

修改内容

主要修改了初始页面,about页面,删除了博客页面与文档页面的例子。

nginx configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
robocon@rc-server:/etc/nginx$ cat nginx.conf 
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

file-service

拟采用 rust 语言实现的 dufs 来提供文件服务。原本的 FileBrowser 由于bug太多,拟弃用。

目前已部署了相关dufs服务,路径在/home/robocon/Files/dufs-install下。配置了启动时的config.yaml,以及相关服务。(但是目前不在局域网下貌似访问不上?)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
serve-path: './Duf'
bind: 0.0.0.0
port: 5252
path-prefix: /

hidden:
  - '*.log'
  - 'tmp'

auth:
  - "rc-admin:qingchun@/:rw" # rc-admin的密码,qingchun,当访问 https://rcserver:5252/ 时,使用该账号密码登录。

allow-upload: true
allow-delete: true
allow-search: true
allow-symlink: false
allow-archive: true
enable-cors: true
render-try-index: true
render-spa: false
compress: medium
log-format: default
log-file: "/home/robocon/Files/dufs-install/dufs.log"

安装与启动方式

建议通过二进制形式安装,直接从 dufs-Releases 页面下载系统对应的二进制包。

采用 systemd 方式配置启动:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Unit]
Description=Gogs
After=network.target

[Service]
Type=simple
User=git
Group=git
WorkingDirectory=/home/git/gogs
ExecStart=/home/git/gogs/gogs web
Restart=always
RestartSec=2s
Environment=USER=git HOME=/home/git

# Some distributions may not support these hardening directives. If you cannot start the service due
# to an unknown option, comment out the ones not supported by your version of systemd.
ProtectSystem=full
PrivateDevices=yes
PrivateTmp=yes
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

配置文件

参考 README#Configuration File 修改配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
serve-path: '.' # 修改为提供共享文件夹的地址
bind: 0.0.0.0   # 全局监听
port: 5203      # 一个不与其他服务冲突的端口
path-prefix: /dufs
hidden:         # 指定需要隐藏的文件,允许正则匹配
  - tmp
  - '*.log'
  - '*.lock'
auth:           # 指定访问控制,@前是'用户名:密码',@后是'文件夹:访问权限'组成的列表
  - admin:admin@/:rw
  - user:pass@/src:rw,/share
  - '@/'  # According to the YAML spec, quoting is required.
allow-all: false # allow-是全局设置,一旦设置为false,具体的访问控制将会被覆盖
allow-upload: true
allow-delete: true
allow-search: true
allow-symlink: true # 允许指向根目录外的符号链接
allow-archive: true # 允许压缩zip文件
enable-cors: true
render-index: true # 当指定的目录不存在时,如果不存在./index.html页面,则显示404 not found ??——是否理解正确?
render-try-index: true # 当指定的目录不存在时,如果不存在./index.html页面,则显示根目录列表 ??——是否理解正确?
render-spa: true
assets: ./assets/ # 指定网页的样式文件(html,css,etc.)存储的文件夹
log-format: '$remote_addr "$request" $status $http_user_agent'
log-file: ./dufs.log
compress: low
tls-cert: tests/data/cert.pem       # tls(https)公钥
tls-key: tests/data/key_pkcs1.pem   # tls(https)私钥

模块联动

Docsy Site 托管在 gogs 上,所有所有对其仓库的更改均会触发githook重新生成静态页面。这个钩子叫做post-receive,即服务端收到提交后运行的代码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master

while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" = "$branch" ]; then
        # 同步更改到 /home/git/hugo/xjrcBlog/ 文件夹,并且强制与现在仓库样貌保持一致
        git --git-dir=/home/git/hugo/xjrcBlog/.git --work-tree=/home/git/hugo/xjrcBlog fetch origin
        git --git-dir=/home/git/hugo/xjrcBlog/.git --work-tree=/home/git/hugo/xjrcBlog reset --hard origin/master
        # 一个mermaid 图表生成脚本
        python3 /home/git/scripts/git-mermaid.py \
        --repo-name=xjrc-blog \
        --repo-dir=. \
        --output-file=/home/git/hugo/xjrcBlog/content/zh-hans/tools/git-history/xjrc_blog/index.md
        cd /home/git/hugo/xjrcBlog/
        # 不尝试获取系统时间 不使用 Chmod 保护文件属性 --- 脚本不是以root用户运行的,没有对应权限
        /usr/local/bin/hugo --noChmod --noTimes
    fi
done

nginx 其他配置

FastCGI

FastCGI(FastCommon Gateway Interface)全称是“快速通用网关接口”,是一种让客户端(web浏览器)与Web服务器(nginx等)程序进行通信(数据传输)的协议。

FastCGI的工作原理如下:

  • Web Server启动同时,加载FastCGI进程管理器(nginx的php-fpm或者IIS的ISAPI或Apache的Module)
  • FastCGI进程管理器读取php.ini配置文件,对自身进行初始化,启动多个CGI解释器进程(php-cgi),等待来自Web Server的连接。
  • 当Web Server接收到客户端请求时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server会将相关环境变量和标准输入发送到FastCGI子进程php-cgi进行处理
  • FastCGI子进程完成处理后将数据按照CGI规定的格式返回给Web Server,然后关闭FastCGI子进程或者等待下一次请求。

所以说,需要按照配置文件/etc/nginx/fastcgi.conf将 Nginx 的请求环境变量打包并传给 FastCGI 后端。FastCGI的优势在于它可以缓存进程,避免了每次请求都要创建和销毁进程的开销,提高了服务器的性能和响应速度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  REMOTE_USER        $remote_user;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;