.gitbay/wiki/Architecture/03-Deployment.org

ba0a7d33f3a65ce53aafb074fda1682cf1cecfdf
gitbay/.gitbay/wiki/Architecture/03-Deployment.org rendered · source · history · blame · raw

80 lines · 7015 bytes

 1#+title: Deployment and network
 2
 3[[file:diagrams/03-deployment.svg]]
 4
 5The reference deployment is one Linux host built from
 6=deploy/cloud-init.yaml=, with the daemon installed by =make deploy=
 7(=deploy/install.sh=) and the CI runner by =make deploy-runner=. The
 8statements in this document about the host rest on those files.
 9
10* Listeners
11
12| Port / path          | Protocol          | Owner      | Default     | Auth                                   | Code                                  |
13|----------------------+-------------------+------------+-------------+----------------------------------------+---------------------------------------|
14| 22/tcp               | SSH               | gitbayd    | on          | public key; unknown keys only reach =register= when registration is open | =cmd/gitbayd/main.go=, =internal/sshd/sshd.go= |
15| 443/tcp              | HTTPS             | gitbayd    | on          | none for pages; session cookie; bearer token for the API | =cmd/gitbayd/main.go=        |
16| 80/tcp               | HTTP              | gitbayd    | on with ACME| none; ACME HTTP-01 and redirect only   | =cmd/gitbayd/main.go=         |
17| 9418/tcp             | git://            | gitbayd    | off         | none; public repositories only         | =internal/gitd=                       |
18| 2222/tcp             | SSH (operator)    | host sshd  | on          | public key, no passwords, fail2ban     | =deploy/cloud-init.yaml=        |
19| =<root>/hook.sock=   | Unix socket       | gitbayd    | on          | mode 0600; peer uid must be the daemon's (Linux); per-push token | =internal/hookd/hookd.go= |
20
21With =ssh.mode = system= the host's sshd serves port 22 instead and
22invokes =gitbayd authorized-keys= and =gitbayd shell=
23(=cmd/gitbayd/main.go=).
24
25HTTP server limits: =ReadHeaderTimeout= 10 s, =IdleTimeout= 2 min,
26=MaxHeaderBytes= 64 KiB, no =WriteTimeout= so long git transfers and
27live build logs can stream (=cmd/gitbayd/main.go=).
28
29There is no metrics endpoint. =/healthz= reports the deployed commit and
30a database check.
31
32* Processes and accounts
33
34| Unit                   | User        | Hardening (from the unit files)                                                                   |
35|------------------------+-------------+---------------------------------------------------------------------------------------------------|
36| =gitbayd.service=      | =gitbay=    | =CAP_NET_BIND_SERVICE= only; =NoNewPrivileges=; =ProtectSystem=strict= with write access to =/var/lib/gitbay= and =/var/backups/gitbay= only; =ProtectHome=; =PrivateTmp=; =PrivateDevices=; kernel, clock and cgroup protections; =RestrictNamespaces=; =MemoryDenyWriteExecute=; =RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX=; =SystemCallFilter=@system-service= (=deploy/cloud-init.yaml=) |
37| =gitbay-runner.service=| =ci-runner= | =MemoryMax=6G=, =CPUQuota=300%=, =Delegate=yes=, =KillMode=mixed=, =RestrictSUIDSGID=yes=. =NoNewPrivileges=, =ProtectKernelTunables= and =ProtectControlGroups= are relaxed because rootless podman needs =newuidmap=, a proc mount and a writable delegated cgroup; the reasons are in =deploy/gitbay-runner.override.conf= |
38| CI containers          | subordinate uids of =ci-runner= | rootless podman, =--pull=never=, operator-provisioned image; see [[file:07-CI-and-Supply-Chain.org][7. CI]] |
39| backup, db-backup, gc, monitor timers | =gitbay= | nightly full archive, hourly database snapshot, weekly =git gc=, hourly health heartbeat (=deploy/cloud-init.yaml=) |
40
41* Filesystem
42
43| Path                              | Contents                                   | Mode set by code / deploy |
44|-----------------------------------+--------------------------------------------+---------------------------|
45| =/var/lib/gitbay= (=server.root=) | everything below                           | 0750 (cloud-init)         |
46| =<root>/gitbay.db=                | SQLite database                            | 0640 (=internal/store/store.go=) |
47| =<root>/repos/<owner>/<name>.git= | bare repositories                          | process umask             |
48| =<root>/lfs=                      | LFS objects, content-addressed             | 0755 directories (=internal/lfs/lfs.go=) |
49| =<root>/ssh/host_ed25519=         | SSH host key                               | 0600 in a 0700 directory (=internal/sshd/sshd.go=) |
50| =<root>/acme=                     | ACME account key and certificates          | autocert defaults         |
51| =<root>/hooks=                    | generated hook scripts                     | 0755                      |
52| =/etc/gitbay/config.toml=         | configuration, including SMTP password     | 0640 (cloud-init)         |
53| =/var/backups/gitbay=             | backup archives                            | 0750 (cloud-init)         |
54
55* Outbound connections from gitbayd
56
57| Destination            | Trigger                       | TLS                                          | Guard                                                          |
58|------------------------+-------------------------------+----------------------------------------------+----------------------------------------------------------------|
59| ACME directory         | certificate issue and renewal | yes                                          | host policy limits names to the site and claimed pages domains (=main.go=) |
60| SMTP relay             | queued mail                   | STARTTLS required for a non-local relay, or implicit TLS | =mail.require_tls=; Go's =PlainAuth= will not send credentials over plaintext to a non-local host (=internal/mail/mail.go=) |
61| APNs                   | queued push                   | yes, HTTP/2                                  | provider token signed with the operator's .p8 key              |
62| Webhook URLs           | recorded events               | yes when https; certificate verified         | private, shared, loopback, link-local and multicast targets refused at save and again at connect time; no redirects (=internal/webhook/webhook.go=) |
63| Mirror URLs            | mirror schedule               | per URL                                      | address check at save and before each sync; git pinned to the checked addresses, no redirects (=internal/mirror/mirror.go=) |
64| Package registries     | dependency checks             | yes                                          | fixed hosts; only the package name varies (=internal/deps/registry.go=) |
65
66* Host firewall
67
68=deploy/cloud-init.yaml= opens 22, 80, 443 and 2222 inbound with ufw.
69Outbound traffic is not restricted, including from CI containers. See
70[[file:10-Known-Gaps.org][10. Known gaps]].
71
72* Change path
73
741. A signed commit merged to =main= through a merge request (direct
75   pushes to =main= are refused by =require-mr=).
762. =make deploy= refuses a dirty tree (=Makefile= =preflight=), builds
77   with the commit stamped in, copies the binary over operator SSH,
78   runs =gitbayd check-config=, restarts the unit
79   (=deploy/install.sh=).
803. =/healthz= reports the commit now serving.