Author | zPlus <zplus@peers.community> 2022-08-14 03:14:27 |
Committer | zPlus <zplus@peers.community> 2022-08-14 03:14:27 |
Commit | db2fb75 (patch) |
Tree | 448ce38 |
Parent(s) |
-rw-r--r-- | documentation/administrators | 171 | ||
?--------- | documentation/installation | 134 | ||
-rw-r--r-- | documentation/users | 79 |
index 6d56364..50a60b7 | |||
old size: 333B - new size: 6K | |||
@@ -1,14 +1,167 @@ | |||
1 | - | # Adding new users | |
1 | + | CLIF makes use of a stack of components that are configured for working together. | |
2 | + | These are described below. They are all optional and they only need be installed | |
3 | + | if the specific functionality is needed. | |
2 | 4 | ||
3 | - | 1. Clone gitolite-admin.git repository | |
4 | - | 2. Add user key into gitolite-admin/keydir/<username>.pub | |
5 | 5 | ||
6 | - | # Assign namespaces to users | |
7 | 6 | ||
8 | - | 1. Clone gitolite-admin.git repository | |
9 | - | 2. Add rule into gitolite-admin/conf/gitolite.conf | |
10 | 7 | ||
11 | - | repo namespace/..* | |
12 | - | C = username | |
13 | - | RW+ = username | |
8 | + | Gitolite | |
9 | + | ------------------------------------------------------------------------------- | |
10 | + | ||
11 | + | This component is not required if CLIF is being installed as a personal instance | |
12 | + | for a single user. If that's the case, this component can be ignored. | |
13 | + | For muli-user instances tha require fine-grained access control, this component | |
14 | + | is required and should be installed. | |
15 | + | ||
16 | + | Follow the instructions at https://gitolite.com/gitolite/fool_proof_setup.html for | |
17 | + | installing Gitolite. As a quick reference this is how to install Gitolite for user | |
18 | + | "git": | |
19 | + | ||
20 | + | su - git | |
21 | + | git clone https://github.com/sitaramc/gitolite | |
22 | + | gitolite/install -to $HOME/bin | |
23 | + | $HOME/bin/gitolite setup -pk <admin_key>.pub | |
24 | + | ||
25 | + | Gitolite does not do authentication, it only does authorization. The name of the | |
26 | + | logged in user is provided to Gitolite by SSH or by the web server, after authentication. | |
27 | + | In order to allow anonymous HTTP clones, the web UI automatically sets a generic | |
28 | + | username value of "anonymous". We need to let Gitolite know what the unauthenticated | |
29 | + | user is going to be named. To do this, add the following line in ~/.gitolite.rc | |
30 | + | in the section "rc variables used by various features". This is explained at | |
31 | + | https://gitolite.com/gitolite/http.html#allowing-unauthenticated-access | |
32 | + | ||
33 | + | HTTP_ANON_USER => 'anonymous', | |
34 | + | ||
35 | + | Also enable non-core commands that are useful to us. These commands are shipped | |
36 | + | with Gitolite but disabled by default. A list of available commands can be found | |
37 | + | at https://gitolite.com/gitolite/list-non-core.html | |
38 | + | ||
39 | + | 'ENABLE' => [ | |
40 | + | ... existing commands | |
41 | + | ||
42 | + | # Allow to change HEAD reference (default branch) like this: | |
43 | + | # ssh git@host symbolic-ref <repo> HEAD refs/heads/<name> | |
44 | + | 'symbolic-ref', | |
45 | + | ] | |
46 | + | ||
47 | + | Administration is done by cloning the gitolite-admin repository. | |
48 | + | For adding new users, add their public key to gitolite-admin/keydir/<username>.pub | |
49 | + | and then create a namespace in gitolite-admin/conf/gitolite.conf so they can create | |
50 | + | new repositories: | |
51 | + | ||
52 | + | repo <username>/..* | |
53 | + | C = <username> | |
54 | + | RW+ = <username> | |
14 | 55 | R = @all | |
56 | + | ||
57 | + | ||
58 | + | ||
59 | + | ||
60 | + | Web UI | |
61 | + | ------------------------------------------------------------------------------- | |
62 | + | ||
63 | + | This is a read-only web interface for displaying Git repositories and mailing lists. | |
64 | + | ||
65 | + | 1. Clone the CLIF repository | |
66 | + | su - git | |
67 | + | git clone https://clif.peers.community/zplus/clif.git /home/git/clif | |
68 | + | ||
69 | + | 2. Install the Python dependencies | |
70 | + | cd /home/git/clif | |
71 | + | python3 -m venv venv | |
72 | + | venv/bin/pip install -r requirements.txt | |
73 | + | ||
74 | + | 3. Configure it | |
75 | + | web.py contains a list of options at the top of the file. Configure these as needed. | |
76 | + | The most important one is REPOSITORIES_ROOT which specifies where the program should | |
77 | + | scan for repositories. If Gitolite is installed this should be the path to Gitolite's | |
78 | + | "repositories" folder, otherwise any other folder containing Git repositories. | |
79 | + | ||
80 | + | 4. Install a SystemD service for controlling the UI service: | |
81 | + | cp web.service /etc/systemd/system/clif-web.service | |
82 | + | systemctl daemon-reload | |
83 | + | systemctl enable clif-web | |
84 | + | systemctl start clif-web | |
85 | + | ||
86 | + | ||
87 | + | ||
88 | + | ||
89 | + | HTTP reverse proxy + Let's Encrypt certificate | |
90 | + | ------------------------------------------------------------------------------- | |
91 | + | ||
92 | + | This section shows how to configure lighttpd as a reverse proxy for the web UI, | |
93 | + | with also a TLS certificate. | |
94 | + | ||
95 | + | apt-get install certbot | |
96 | + | certbot certonly --webroot -w /var/www/html -d <your-domain.tld> | |
97 | + | ||
98 | + | The cert is created in /etc/letsencrypt/live/<your-domain.tld>/ | |
99 | + | Lighttpd requires the certificate and private key to be in a single file: | |
100 | + | ||
101 | + | cat privkey.pem cert.pem > privkey+cert.pem | |
102 | + | ||
103 | + | Add to lighttpd configuration: | |
104 | + | ||
105 | + | $ vim /etc/lighttpd/lighttpd.conf | |
106 | + | ||
107 | + | server.modules += ( | |
108 | + | "mod_fastcgi", | |
109 | + | "mod_proxy", | |
110 | + | ) | |
111 | + | ||
112 | + | # Redirect HTTP to HTTPS | |
113 | + | $HTTP["scheme"] == "http" { | |
114 | + | url.redirect = ("" => "https://${url.authority}${url.path}${qsa}") | |
115 | + | url.redirect-code = 308 | |
116 | + | } | |
117 | + | ||
118 | + | $SERVER["socket"] == ":443" { | |
119 | + | ssl.engine = "enable" | |
120 | + | ssl.pemfile = "/etc/letsencrypt/live/<your-domain.tld>/privkey+cert.pem" | |
121 | + | ssl.ca-file = "/etc/letsencrypt/live/<your-domain.tld>/chain.pem" | |
122 | + | ||
123 | + | $HTTP["host"] == "<your-domain.tld>" { | |
124 | + | proxy.server = ( | |
125 | + | "" => ( | |
126 | + | ( "host" => "127.0.0.1", "port" => 5000 ) | |
127 | + | ) | |
128 | + | ) | |
129 | + | } | |
130 | + | } | |
131 | + | ||
132 | + | Let's Encrypt certificates expire every 90 days, so a cron job needs to be set up | |
133 | + | that will generate a new privkey+cert.pem file and reload lighttpd. | |
134 | + | ||
135 | + | $ vim /etc/cron.weekly/clif-letsencrypt | |
136 | + | $ chmod +x /etc/cron.weekly/clif-letsencrypt | |
137 | + | ||
138 | + | # Content of "clif-letsencrypt" | |
139 | + | certbot renew | |
140 | + | cd /etc/letsencrypt/live/<your-domain.tld> | |
141 | + | cat privkey.pem cert.pem > privkey+cert.pem | |
142 | + | service lighttpd restart | |
143 | + | ||
144 | + | ||
145 | + | ||
146 | + | ||
147 | + | Mailing Lists | |
148 | + | ------------------------------------------------------------------------------- | |
149 | + | ||
150 | + | 1. There are a couple of settings at the top of emails.py. Change them as needed. | |
151 | + | ||
152 | + | 2. Add the following to /etc/postfix/main.cf. This will forward all emails to the | |
153 | + | system user "git" | |
154 | + | ||
155 | + | luser_relay = git | |
156 | + | local_recipient_maps = | |
157 | + | ||
158 | + | 3. Create the file /home/git/.forward with the content: | |
159 | + | ||
160 | + | |/home/git/clif/emails.py | |
161 | + | ||
162 | + | This is a sendmail file (also used by postfix) for deciding how incoming messages | |
163 | + | shall be delivered to the the system user. For our purposes, we instruct postfix | |
164 | + | to pipe all the emails for user "git" to our script. | |
165 | + | Make sure the script is executable. | |
166 | + | ||
167 | + | TODO Add documentation for SPF, DKIM, DMARC, SRS, ARC (and more..?) |
index 0fdaee7..0000000 | |||
old size: 4K - new size: 0B | |||
deleted file mode: -rw-r--r-- |
@@ -1,134 +0,0 @@ | |||
1 | - | Gitolite | |
2 | - | ------------------------------------------------------------------------------- | |
3 | - | ||
4 | - | Follow instructions at https://gitolite.com/gitolite/fool_proof_setup.html | |
5 | - | ||
6 | - | TL;DR: | |
7 | - | su - git | |
8 | - | git clone https://github.com/sitaramc/gitolite | |
9 | - | gitolite/install -to $HOME/bin | |
10 | - | $HOME/bin/gitolite setup -pk <admin_key>.pub | |
11 | - | ||
12 | - | Gitolite does not do authentication, it only does authorization. The name of the | |
13 | - | logged in user is provided as an environment variable. In order to allow anonymous | |
14 | - | HTTP clones, ie. for allowing "git clone https://..." without any authentication, | |
15 | - | the web app automatically sets a generic username value of "anonymous". We need | |
16 | - | to let Gitolite know what the unauthenticated user is going to be called so that | |
17 | - | it can check authorization. To do this, just add the following to ~/.gitolite.rc | |
18 | - | in the section marked "rc variables used by various features". This is explained | |
19 | - | at https://gitolite.com/gitolite/http.html#allowing-unauthenticated-access | |
20 | - | ||
21 | - | HTTP_ANON_USER => 'anonymous', | |
22 | - | ||
23 | - | Enable some non-core commands that are useful to us. This is done by editing ~/.gitolite.rc: | |
24 | - | ||
25 | - | 'ENABLE' => [ | |
26 | - | ... existing commands | |
27 | - | ||
28 | - | # Allow to change HEAD reference (default branch) like this: | |
29 | - | # ssh git@host symbolic-ref <repo> HEAD refs/heads/<name> | |
30 | - | 'symbolic-ref', | |
31 | - | ] | |
32 | - | ||
33 | - | ||
34 | - | ||
35 | - | ||
36 | - | Web UI | |
37 | - | ------------------------------------------------------------------------------- | |
38 | - | ||
39 | - | The CLIF repository is assumed to having been cloned into /home/git/clif. | |
40 | - | ||
41 | - | 1. There are a couple of settings at the top of web.py. Change them. | |
42 | - | ||
43 | - | 2. Install the Python dependencies: | |
44 | - | ||
45 | - | cd /home/git/clif | |
46 | - | python3 -m venv venv | |
47 | - | venv/bin/pip install -r requirements.txt | |
48 | - | ||
49 | - | 3. Install a SystemD service for controlling the UI: | |
50 | - | ||
51 | - | cp web.service /etc/systemd/system/clif-web.service | |
52 | - | systemctl daemon-reload | |
53 | - | systemctl enable clif-web | |
54 | - | systemctl start clif-web | |
55 | - | ||
56 | - | ||
57 | - | ||
58 | - | ||
59 | - | Mailing Lists | |
60 | - | ------------------------------------------------------------------------------- | |
61 | - | ||
62 | - | 1. There are a couple of settings at the top of emails.py. Change them. | |
63 | - | ||
64 | - | 2. Add the following to /etc/postfix/main.cf. This will forward all emails to the | |
65 | - | system user "git" | |
66 | - | ||
67 | - | luser_relay = git | |
68 | - | local_recipient_maps = | |
69 | - | ||
70 | - | 3. Create the file /home/git/.forward with the content: | |
71 | - | ||
72 | - | |/home/git/clif/emails.py | |
73 | - | ||
74 | - | This is a sendmail file, also used by postfix, for deciding how incoming messages | |
75 | - | shall be delivered to the the system user. For our purposes, we instruct postfix | |
76 | - | to pipe all the emails for user "git" to our script. Make sure the script is | |
77 | - | executable. | |
78 | - | ||
79 | - | ||
80 | - | ||
81 | - | ||
82 | - | Let's Encrypt certificate | |
83 | - | ------------------------------------------------------------------------------- | |
84 | - | ||
85 | - | apt-get install certbot | |
86 | - | certbot certonly --webroot -w /var/www/html -d your-domain.tld | |
87 | - | ||
88 | - | The cert is created in /etc/letsencrypt/live/<your-domain.tld>/ | |
89 | - | ||
90 | - | Lighttpd requires the certificate and private key to be in a single file: | |
91 | - | ||
92 | - | cat privkey.pem cert.pem > privkey+cert.pem | |
93 | - | ||
94 | - | Configure lighttpd reverse proxy: | |
95 | - | ||
96 | - | vim /etc/lighttpd/lighttpd.conf | |
97 | - | ||
98 | - | server.modules += ( | |
99 | - | "mod_fastcgi", | |
100 | - | "mod_proxy", | |
101 | - | ) | |
102 | - | ||
103 | - | $HTTP["scheme"] == "http" { | |
104 | - | url.redirect = ("" => "https://${url.authority}${url.path}${qsa}") | |
105 | - | url.redirect-code = 308 | |
106 | - | } | |
107 | - | ||
108 | - | $SERVER["socket"] == ":443" { | |
109 | - | ssl.engine = "enable" | |
110 | - | ssl.pemfile = "/etc/letsencrypt/live/<your-domain.tld>/privkey+cert.pem" | |
111 | - | ssl.ca-file = "/etc/letsencrypt/live/<your-domain.tld>/chain.pem" | |
112 | - | ||
113 | - | $HTTP["host"] == "<your-domain.tld>" { | |
114 | - | proxy.server = ( | |
115 | - | "" => ( | |
116 | - | ( "host" => "127.0.0.1", "port" => 5000 ) | |
117 | - | ) | |
118 | - | ) | |
119 | - | # server.document-root = "/var/www/html" # Document Root | |
120 | - | # server.errorlog = "/" | |
121 | - | # accesslog.filename = "/" | |
122 | - | } | |
123 | - | } | |
124 | - | ||
125 | - | Let's Encrypt certificates expire every 90 days, so we need to setup a cron job | |
126 | - | that will generate a new privkey+cert.pem file, and reload lighttpd too. | |
127 | - | ||
128 | - | vim /etc/cron.weekly/clif-letsencrypt | |
129 | - | chmod +x /etc/cron.weekly/clif-letsencrypt | |
130 | - | ||
131 | - | certbot renew | |
132 | - | cd /etc/letsencrypt/live/<your-domain.tld> | |
133 | - | cat privkey.pem cert.pem > privkey+cert.pem | |
134 | - | service lighttpd restart |
index 030d339..8ab79fd | |||
old size: 2K - new size: 2K | |||
@@ -1,11 +1,11 @@ | |||
1 | - | General usage | |
1 | + | Users | |
2 | 2 | ------------------------------------------------------------------------------- | |
3 | 3 | ||
4 | - | # List of available commands over SSH | |
4 | + | # List commands available to the user over SSH | |
5 | 5 | ||
6 | 6 | ssh git@example.org help | |
7 | 7 | ||
8 | - | # List of user repositories and access permissions | |
8 | + | # List user repositories and access permissions | |
9 | 9 | ||
10 | 10 | ssh git@example.org info | |
11 | 11 | ||
@@ -15,34 +15,35 @@ General usage | |||
15 | 15 | Repositories | |
16 | 16 | ------------------------------------------------------------------------------- | |
17 | 17 | ||
18 | - | # Cloning a repository anonymously | |
18 | + | # Clone repository anonymously | |
19 | 19 | ||
20 | - | git clone https://example.org/repository.git | |
20 | + | git clone https://example.org/<repository>.git | |
21 | 21 | ||
22 | - | # Cloning a repository as registered users | |
22 | + | # Clone repository (for registered users) | |
23 | 23 | ||
24 | - | git clone git@example.org:repository | |
24 | + | git clone git@example.org:<repository> | |
25 | 25 | ||
26 | - | # Creating a new repository | |
27 | - | Either clone, or push to, a nonexistent repository. It will be initiated automatically | |
28 | - | as long as the user has write permission. | |
26 | + | # Create new repository | |
29 | 27 | ||
30 | - | git clone git@example.org:repository | |
31 | - | git push git@example.org:repository master | |
28 | + | Either clone, or push to, a nonexistent path. A new repository will be initiated | |
29 | + | automatically. | |
30 | + | ||
31 | + | git clone git@example.org:<repository> | |
32 | + | git push git@example.org:<repository> <branch> | |
32 | 33 | ||
33 | 34 | # Set repository description | |
34 | 35 | ||
35 | - | ssh git@example.org desc <repositoy> "<description>" | |
36 | + | ssh git@example.org desc <repository> <description> | |
36 | 37 | ||
37 | - | # Pushing to a repository | |
38 | + | # Push to repository | |
38 | 39 | ||
39 | - | git push git@example.org:repository.git | |
40 | + | git push git@example.org:<repository> | |
40 | 41 | ||
41 | - | # Change default branch by repoint HEAD to other branches | |
42 | + | # Change default branch by repointing HEAD | |
42 | 43 | ||
43 | - | ssh git@example.org symbolic-ref repository.git HEAD refs/heads/main | |
44 | + | ssh git@example.org symbolic-ref <repository> HEAD refs/heads/<branch> | |
44 | 45 | ||
45 | - | # Delete repository (D command) | |
46 | + | # Delete repository (with D command) | |
46 | 47 | ||
47 | 48 | ssh git@example.org D unlock <repository> | |
48 | 49 | ssh git@example.org D rm <repository> | |
@@ -53,34 +54,38 @@ as long as the user has write permission. | |||
53 | 54 | Mailing lists | |
54 | 55 | ------------------------------------------------------------------------------- | |
55 | 56 | ||
56 | - | Mailing lists are where collaboration happens, and they are stored in repositories | |
57 | - | too. | |
58 | - | ||
59 | - | # Create a new mailing list | |
57 | + | # Create new mailing list | |
60 | 58 | ||
61 | 59 | Create a new repository with the suffix ".mlist": | |
62 | 60 | ||
63 | - | git clone git@example.org:project.mlist | |
61 | + | git clone git@example.org:<repository>.mlist | |
62 | + | ||
63 | + | CLIF will then begin accepting emails for <repository>@example.org and it will | |
64 | + | store them inside the <repository>.mlist repository. | |
65 | + | ||
66 | + | # Subscribe to lists | |
67 | + | ||
68 | + | Send an email to the list address with the +subscribe suffix. | |
64 | 69 | ||
65 | - | CLIF will then begin accepting emails for project@example.org and store them | |
66 | - | inside the "project.mlist" repository. | |
70 | + | From: You <you@example.org> | |
71 | + | To: <repository>+subscribe@example.org | |
67 | 72 | ||
68 | - | # Subscribe to a list | |
73 | + | # Unsubscribe from lists | |
69 | 74 | ||
70 | - | Send an email to the list address with the +subscribe suffix. For example | |
71 | - | username/reponame+subscribe@example.org | |
75 | + | Send an email to the list address with the +unsubscribe suffix. | |
72 | 76 | ||
73 | - | # Unsubscribe from a list | |
77 | + | From: You <you@example.org> | |
78 | + | To: <repository>+unsubscribe@example.org | |
74 | 79 | ||
75 | - | Send an email to the list address with the +unsubscribe suffix. For example | |
76 | - | username/reponame+unsubscribe@example.org | |
80 | + | # New thread | |
77 | 81 | ||
78 | - | # New threads | |
82 | + | Send a new email to any list address. | |
79 | 83 | ||
80 | - | New threads are created simply by sending a new email to the list address. An account | |
81 | - | is not required for starting new threads and participating in discussions. | |
84 | + | # Join existing thread | |
82 | 85 | ||
83 | - | # Join an existing thread | |
86 | + | Send an email containing the "In-Reply-To: <Message-ID>" header, where <Message-ID> | |
87 | + | is the ID of any previous message. | |
84 | 88 | ||
85 | - | It is possible to join an existing thread by sending an email containing the header | |
86 | - | "In-Reply-To: <Message-ID>", where <Message-ID> is the ID value of any previous message. | |
89 | + | From: You <you@example.org> | |
90 | + | To: <repository>@example.org | |
91 | + | In-Reply-To: <Message-ID> |