Commit | Line | Data |
---|---|---|
4ccc706c AT |
1 | # Overview # |
2 | ||
3 | These notes cover the creation of a server, hosted with Linode, running Debian | |
4 | Linux, offering the following services: | |
5 | ||
6 | - Mail server | |
7 | ||
8 | - SMTP via postfix | |
9 | ||
10 | - IMAP via dovecot | |
11 | ||
12 | - Realtime blacklists for SPAM rejection | |
13 | ||
14 | - MySQL for virtual domain and user management. | |
15 | ||
16 | - Web server | |
17 | ||
18 | - Apache as central HTTP server with multiple vhosts. | |
19 | ||
562bd187 | 20 | - [CMless](http://git.subgeniuskitty.com/cmless/.git) as CGI for content management |
4ccc706c AT |
21 | |
22 | - ACME for automated SSL certificate management | |
23 | ||
24 | - Git server | |
25 | ||
26 | - SSH-based, authenticated read-write access to all git repositories | |
27 | ||
28 | - Anonymous read-only access to a subset of git repositories via: | |
29 | ||
6bce4d40 AT |
30 | - Customized [gitweb](http://git.subgeniuskitty.com/gitweb-sgk/.git) for |
31 | GUI git browsing with syntax highlighting, diffs, etc | |
4ccc706c AT |
32 | |
33 | - Git-daemon for cloning repositories via the `git://` protocol | |
34 | ||
35 | These notes are a high-level checklist for my reference rather than a | |
36 | step-by-step installation guide for the public. That means they make no attempt | |
37 | to explain all options at each step, rather that they mention only the options | |
38 | I use on my servers. It also means they use my domains, my file system paths, | |
39 | etc in the examples. | |
40 | ||
41 | ||
42 | # TODO List # | |
43 | ||
4ccc706c AT |
44 | - Take a snapshot on Linode's backup service once the basic services are |
45 | operational. | |
46 | ||
7c21ac6b | 47 | - Migrate mail server. Delete old linode vserver after downloading a disk image. |
4ccc706c AT |
48 | |
49 | - Finish this documentation. | |
50 | ||
51 | - Improve CSS on gitweb, especially for displaying READMEs. | |
52 | ||
6bce4d40 AT |
53 | - Add some form of web logfile viewing. |
54 | ||
4ccc706c AT |
55 | |
56 | # Basic Configuration # | |
57 | ||
58 | ||
59 | ## General Information ## | |
60 | ||
61 | **Name:** SGK-Main-2020 | |
62 | ||
63 | **OS:** Debian 10 | |
64 | ||
65 | **Creation Date:** 2020-11-01 | |
66 | ||
67 | **Filesystem Points of Interest:** | |
68 | ||
69 | - `/srv/apache_vhosts`: Contains websites hosted by Apache2. See | |
70 | `/etc/apache2/sites_available` for vhost configurations. | |
71 | ||
72 | - `/srv/git`: Master location for bare git repositories. All are private. | |
73 | ||
74 | - `/srv/gitweb_cache`: Contains checked out copies of git repositories from | |
75 | `/srv/git`, publicly visible via `gitweb` and cloneable via `git-daemon`. | |
76 | ||
77 | ||
78 | ## Preparation ## | |
79 | ||
80 | Setup DNS entries for `subgeniuskitty.com` and `logicavalanche.com` through | |
81 | Linode. Remember to do IPv4 and IPv6 entries for the bare domain, `www`, | |
82 | `mail`, and `git`. | |
83 | ||
84 | Create a new Debian 10 on Linode and update the system with `apt-get update && | |
85 | apt-get upgrade`. | |
86 | ||
87 | Add a user via `adduser ataylor` and following the prompts. Edit | |
88 | `/etc/ssh/sshd_config` to set `PermitRootLogin: no` and restart SSH. For both | |
89 | the `ataylor` user and `root`, add the line `set mouse=` to `~/.vimrc` in order | |
90 | to disable mouse support in `vim`, allowing normal mark-and-paste in the | |
91 | terminal. | |
92 | ||
93 | Install useful packages: | |
94 | ||
95 | apt-get install net-tools screen bzip2 zip | |
96 | ||
97 | ||
98 | # Web Server # | |
99 | ||
100 | ||
101 | ## HTTP: Apache2 ## | |
102 | ||
103 | Install Apache2. | |
104 | ||
105 | apt-get install apache2 | |
106 | ||
b989fcd3 AT |
107 | If not already defined elsewhere, add a `ServerName 127.0.0.1` entry to the |
108 | bottom of `/etc/apache2/apache2.conf`, or whatever is appropriate. | |
2fbf9e1e | 109 | |
4ccc706c AT |
110 | Since we use `/srv` instead of `/var/www`, edit `/etc/apache2/apache2.conf` to |
111 | comment out the `<Directory ...>` entry for `/var/www` and replace it with | |
112 | this: | |
113 | ||
114 | <Directory /srv/> | |
115 | Options Indexes FollowSymLinks | |
116 | AllowOverride None | |
117 | Require all granted | |
118 | </Directory> | |
119 | ||
120 | Make and edit the file `/srv/apache_vhosts/default/index.html` with (rewritten) | |
121 | contents: | |
122 | ||
123 | <p>Invalid VHost</p> | |
124 | <p>Contact user @at@ domain .dot. com</p> | |
125 | ||
126 | Ensure everything under `/srv/apache_vhosts`, including that directory itself, | |
127 | is owned recursively by `www-data:www-data`. | |
128 | ||
129 | Edit `/etc/apache2/sites-available/000-default.conf` and | |
130 | `/etc/apache2/sites-available/000-default.conf`, changing references for the | |
131 | default sites from `/var/www/...` to `/srv/apache_vhosts/...` as necessary. | |
132 | ||
133 | Reload Apache2 with `systemctl reload apache2` and check status with `systemctl | |
134 | status apache2`. | |
135 | ||
136 | ||
137 | ### SSL ### | |
138 | ||
6bce4d40 AT |
139 | Install certbot and generate a key for its use. |
140 | ||
141 | apt-get install certbot | |
142 | openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 | |
4ccc706c | 143 | |
6bce4d40 AT |
144 | Create `/etc/apache2/conf-available/ssl-params.conf` with the following |
145 | contents. | |
146 | ||
147 | SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 | |
148 | SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 | |
149 | SSLHonorCipherOrder off | |
150 | SSLSessionTickets off | |
151 | ||
152 | SSLUseStapling On | |
153 | SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" | |
154 | ||
155 | Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" | |
156 | Header always set X-Frame-Options SAMEORIGIN | |
157 | Header always set X-Content-Type-Options nosniff | |
158 | ||
159 | SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem" | |
4ccc706c | 160 | |
6bce4d40 | 161 | Enable the new configuration and required mods, then restart Apache2. |
4ccc706c | 162 | |
6bce4d40 AT |
163 | a2enconf ssl-params |
164 | a2enmod ssl | |
165 | a2enmod headers | |
166 | systemctl restart apache2 | |
167 | ||
168 | Retrieve an initial certificate with the following command, modified to match | |
169 | the desired webroot and server names. | |
170 | ||
171 | <http://subgeniuskitty.com> and <http://logicavalanche.com>: | |
172 | ||
173 | certbot certonly --agree-tos --email webmaster@subgeniuskitty.com --webroot -w /srv/apache_vhosts/subgeniuskitty.com/site/data/ -d subgeniuskitty.com -d www.subgeniuskitty.com | |
174 | ||
175 | <http://archive.subgeniuskitty.com> and <http://git.subgeniuskitty.com>: | |
176 | ||
177 | certbot certonly --agree-tos --email webmaster@subgeniuskitty.com --webroot -w /srv/apache_vhosts/archive.subgeniuskitty.com/ -d archive.subgeniuskitty.com | |
178 | ||
179 | Edit `/etc/apache2/sites-available/subgeniuskitty.com`, adding the following | |
180 | `VirtualHost` definition that mostly copies the non-SSL entry. | |
181 | ||
182 | <VirtualHost *:443> | |
183 | SSLEngine on | |
184 | SSLCertificateFile /etc/letsencrypt/live/subgeniuskitty.com/fullchain.pem | |
185 | SSLCertificateKeyFile /etc/letsencrypt/live/subgeniuskitty.com/privkey.pem | |
186 | ||
187 | ...copy of vhost definition for host *:80... | |
188 | </VirtualHost> | |
4ccc706c | 189 | |
6bce4d40 AT |
190 | Edit `/etc/cron.d/certbot` and append `--renew-hook "systemctl reload apache2"` |
191 | to the certbot invokation. | |
4ccc706c | 192 | |
6bce4d40 | 193 | Test with `certbot renew --dry-run`. |
4ccc706c | 194 | |
6bce4d40 | 195 | Repeat the process for any other sites hosted on this server. |
4ccc706c | 196 | |
6bce4d40 | 197 | Backup the `/etc/letsencrypt` folder off-server periodically. |
4ccc706c AT |
198 | |
199 | ||
200 | ## Basic Website ## | |
201 | ||
202 | Using <http://archive.subgeniuskitty.com> as an example of a basic website, | |
203 | create an Apache2 vhost configuration file at | |
204 | `/etc/apache2/sites-available/archive.subgeniuskitty.com.conf`. | |
205 | ||
206 | <VirtualHost *:80> | |
207 | DocumentRoot "/srv/apache_vhosts/archive.subgeniuskitty.com" | |
208 | ServerName archive.subgeniuskitty.com | |
209 | ServerAdmin webmaster@subgeniuskitty.com | |
210 | ErrorLog /var/log/apache2/error_log.archive.subgeniuskitty.com | |
211 | CustomLog /var/log/apache2/access_log.archive.subgeniuskitty.com combined | |
212 | <Directory "/srv/apache_vhosts/archive.subgeniuskitty.com"> | |
213 | Options +FollowSymLinks | |
214 | AllowOverride None | |
215 | Require all granted | |
216 | </Directory> | |
217 | <Directory "/srv/apache_vhosts/archive.subgeniuskitty.com/sites"> | |
218 | Options +FollowSymLinks +Indexes | |
219 | AllowOverride None | |
220 | Require all granted | |
221 | </Directory> | |
222 | </VirtualHost> | |
223 | ||
224 | Make the directory `/srv/apache_vhosts/archive.subgeniuskitty.com`, move your | |
225 | data into it, and ensure everything is owned by `www-data:www-data`. | |
226 | ||
227 | Enable the vhost with `a2ensite archive.subgeniuskitty.com` and `systemctl | |
228 | reload apache2`. | |
229 | ||
230 | ||
231 | ## CMless Website ## | |
232 | ||
233 | Enable `mod_rewrite` and either `mod_cgi` or `mod_cgid` as appropriate with | |
234 | these commands. | |
235 | ||
236 | a2enmod rewrite | |
237 | a2enmod cgid | |
238 | ||
239 | Install `discount` to convert Markdown to HTML. | |
240 | ||
241 | apt-get install discount | |
242 | ||
243 | Create `/etc/apache2/sites-available/subgeniuskitty.com.conf`. | |
244 | ||
245 | <VirtualHost *:80> | |
246 | DocumentRoot "/srv/apache_vhosts/subgeniuskitty.com" | |
247 | ServerName subgeniuskitty.com | |
248 | ServerAlias www.subgeniuskitty.com | |
249 | ServerAdmin webmaster@subgeniuskitty.com | |
250 | ErrorLog /var/log/apache2/error_log.subgeniuskitty.com | |
251 | CustomLog /var/log/apache2/access_log.subgeniuskitty.com combined | |
252 | AddHandler cgi-script .py | |
253 | <Directory "/srv/apache_vhosts/subgeniuskitty.com"> | |
254 | Options -ExecCGI -Indexes | |
255 | AllowOverride None | |
256 | Require all granted | |
257 | </Directory> | |
258 | <Directory "/srv/apache_vhosts/subgeniuskitty.com/bin"> | |
259 | Options ExecCGI | |
260 | AllowOverride None | |
261 | Require all granted | |
262 | </Directory> | |
263 | RewriteEngine On | |
264 | RewriteRule (.*) /srv/apache_vhosts/subgeniuskitty.com/site/data/$1 | |
265 | RewriteCond %{REQUEST_FILENAME} !-f | |
266 | RewriteRule .* /srv/apache_vhosts/subgeniuskitty.com/bin/cmless.py | |
267 | </VirtualHost> | |
268 | ||
269 | Enable the site with `a2ensite subgeniuskitty.com`. | |
270 | ||
562bd187 | 271 | Clone a copy of [CMless](http://git.subgeniuskitty.com/cmless/.git) into |
4ccc706c AT |
272 | `/srv/apache_vhosts/subgeniuskitty.com` and ensure everything is owned by |
273 | `www-data:www-data`. | |
274 | ||
275 | Clone a copy of [the website | |
562bd187 | 276 | data](http://git.subgeniuskitty.com/website_subgeniuskitty.com/.git) into |
4ccc706c AT |
277 | `/srv/apache_vhosts/subgeniuskitty.com/site`. Verify it is owned by |
278 | `ataylor:ataylor` (but still readable by all) so we can update the site | |
279 | remotely with a simple script like this: | |
280 | ||
281 | #!/usr/local/bin/bash | |
282 | # | |
283 | # Usage: No cmdline arguments | |
284 | # Update content of www.subgeniuskitty.com to the latest version. | |
285 | ||
286 | ssh ataylor@git.subgeniuskitty.com "cd /srv/apache_vhosts/subgeniuskitty.com/site && git pull" | |
287 | ||
288 | Reload Apache's configuration with `systemctl reload apache2` and test access | |
289 | to the website. | |
290 | ||
291 | Repeat this process for <http://logicavalanche.com>. | |
292 | ||
293 | ||
294 | # Git Server # | |
295 | ||
296 | The git server provides read-write access to a private collection of bare | |
297 | repositories located at `/srv/git` via SSH. It also provides read-only access | |
298 | to a public collection of normal repositories located at `/srv/gitweb_cache` | |
299 | via <http://git.subgeniuskitty.com/repo_name> through gitweb and via | |
300 | [git://git.subgeniuskitty.com/repo_name](git://git.subgeniuskitty.com/repo_name) | |
301 | through `git-daemon`. | |
302 | ||
303 | ||
304 | ## Read/Write: SSH ## | |
305 | ||
306 | Install git with `apt-get install git`. | |
307 | ||
308 | On my workstation, generate an SSH key with `ssh-keygen -t rsa`. | |
309 | ||
310 | On the server, as user `ataylor`: | |
311 | ||
312 | mkdir ~/.ssh | |
6bce4d40 AT |
313 | chmod 700 ~/.ssh |
314 | touch ~/.ssh/authorized_keys | |
315 | chmod 600 ~/.ssh/authorized_keys | |
4ccc706c AT |
316 | |
317 | Then `cat` the public SSH key from the workstation to the server, appending it | |
318 | onto `~/.ssh/authorized_keys`. | |
319 | ||
320 | Verify ability to login using new certificate. | |
321 | ||
322 | Create a directory `/srv/git` owned by `ataylor:ataylor`. This will hold bare | |
323 | git repositories and act as the central private store for SGK git repos. | |
324 | ||
325 | From the workstation, we can create a new bare repository on the server. For | |
326 | example, packed up in a simple script: | |
327 | ||
328 | #!/usr/local/bin/bash | |
329 | # | |
330 | # Usage: sgkgit-new-repo project_name | |
331 | # Setup a repository on the SGK git server. | |
332 | ||
333 | if [ "$#" -ne 1 ]; then | |
334 | echo "Must specify repo name as only parameter." | |
335 | exit 2 | |
336 | fi | |
337 | ||
338 | ssh ataylor@git.subgeniuskitty.com "git init --bare /srv/git/$@" | |
339 | ||
340 | We then set the remote of an existing repository to the new bare repository. | |
341 | Again as a script: | |
342 | ||
343 | #!/usr/local/bin/bash | |
344 | # | |
345 | # Usage: sgkgit-set-origin project_name | |
346 | # Sets remote to the correct path for 'project_name' on the SGK git server. | |
347 | ||
348 | if [ "$#" -ne 1 ]; then | |
349 | echo "Must specify repo name as only parameter." | |
350 | exit 2 | |
351 | fi | |
352 | ||
353 | git remote remove origin | |
354 | git remote add origin ataylor@git.subgeniuskitty.com:/srv/git/$@ | |
355 | echo "Remember to make the first push with \"git push --set-upstream origin master\"." | |
356 | ||
357 | After the first push to the bare repository on the server, simply `git push` | |
358 | and `git pull` as normal. | |
359 | ||
360 | You can also list the repositories currently on the server with simple SSH commands. | |
361 | ||
362 | #!/usr/local/bin/bash | |
363 | # | |
364 | # Usage: No cmdline arguments. | |
365 | # List all remote repos available on SGK git server. | |
366 | ||
367 | ssh ataylor@git.subgeniuskitty.com "ls -lt /srv/git/" | |
368 | ||
369 | Clone one of these repositories, with remote correspondingly pre-set. | |
370 | ||
371 | #!/usr/local/bin/bash | |
372 | # | |
373 | # Usage: sgkgit-checkout project_name | |
374 | # Clone a local copy of repo "project_name" from SGK git server. | |
375 | ||
376 | if [ "$#" -ne 1 ]; then | |
377 | echo "Must specify repo name as only parameter." | |
378 | exit 2 | |
379 | fi | |
380 | ||
381 | git clone ataylor@git.subgeniuskitty.com:/srv/git/$@ | |
382 | ||
383 | ||
384 | ## Read-Only: Gitweb ## | |
385 | ||
386 | Enable `mod_rewrite` and either `mod_cgi` or `mod_cgid` as appropriate with | |
387 | these commands. | |
388 | ||
389 | a2enmod rewrite | |
390 | a2enmod cgid | |
391 | ||
392 | Install `discount` to convert Markdown to HTML, `highlight` for syntax | |
393 | highlighting, and `gitweb` to pull in any dependencies. | |
394 | ||
395 | apt-get install discount highlight gitweb | |
396 | ||
397 | Create `/etc/apache2/sites-available/git.subgeniuskitty.com.conf`. | |
398 | ||
399 | <VirtualHost *:80> | |
400 | ServerName git.subgeniuskitty.com | |
401 | ServerAdmin webmaster@subgeniuskitty.com | |
402 | ||
403 | DocumentRoot "/srv/apache_vhosts/git.subgeniuskitty.com" | |
404 | ||
405 | ErrorLog /var/log/apache2/error_log.git.subgeniuskitty.com | |
406 | CustomLog /var/log/apache2/access_log.git.subgeniuskitty.com combined | |
407 | ||
408 | <Directory "/srv/apache_vhosts/git.subgeniuskitty.com"> | |
409 | Options +FollowSymLinks +ExecCGI | |
410 | AllowOverride None | |
411 | Require all granted | |
412 | AddHandler cgi-script .cgi | |
413 | DirectoryIndex gitweb.cgi | |
414 | RewriteEngine On | |
415 | RewriteCond %{REQUEST_FILENAME} !-f | |
416 | RewriteCond %{REQUEST_FILENAME} !-d | |
417 | RewriteRule ^.* /gitweb.cgi/$0 [L,PT] | |
418 | </Directory> | |
419 | </VirtualHost> | |
420 | ||
421 | Enable the site with `a2ensite git.subgeniuskitty.com`. | |
422 | ||
562bd187 | 423 | Clone a copy of [the SGK gitweb fork](http://git.subgeniuskitty.com/gitweb-sgk/.git) |
4ccc706c AT |
424 | into `/srv/apache_vhosts/git.subgeniuskitty.com` and ensure everything is owned |
425 | by `ataylor:ataylor` (but world-readable!) so we can update via SSH with a script like this. | |
426 | ||
427 | #!/usr/local/bin/bash | |
428 | # | |
429 | # Usage: No cmdline arguments | |
430 | # Update git.subgeniuskitty.com to the latest version of forked gitweb repo. | |
431 | ||
432 | ssh ataylor@git.subgeniuskitty.com "cd /srv/apache_vhosts/git.subgeniuskitty.com && git pull" | |
433 | ||
434 | This fork makes a few changes to gitweb, displaying READMEs by default, etc. | |
435 | Read the gitweb project's `README.md` for more details. | |
436 | ||
437 | Create a gitweb config file at `/etc/gitweb.conf`. Note that we are adding a | |
438 | `clone url` to the toolbar with the address of our `git-daemon` server. | |
439 | Remember to set that up. | |
440 | ||
441 | $site_name = "git.subgeniuskitty.com"; | |
442 | @git_base_url_list = ("git://git.subgeniuskitty.com"); | |
443 | $projectroot = "/srv/gitweb_cache"; | |
444 | $git_temp = "/tmp"; | |
445 | ||
446 | @stylesheets = ("static/gitweb.css"); | |
447 | $javascript = "static/gitweb.js"; | |
448 | $logo = "static/sgk-logo.png"; | |
449 | $favicon = "static/git-favicon.png"; | |
450 | ||
451 | # git-diff-tree(1) options to use for generated patches | |
452 | @diff_opts = (); | |
453 | ||
454 | # Enable PATH_INFO so the server can produce URLs of the | |
455 | # form: http://git.hokietux.net/project.git/xxx/xxx | |
456 | # This allows for pretty URLs *within* the Git repository, | |
457 | # also needs the Apache rewrite rules for full effect. | |
458 | $feature{'pathinfo'}{'default'} = [1]; | |
459 | ||
460 | # HTML text to include as home page header. | |
461 | $home_text = "indextext.html"; | |
adccee6a AT |
462 | |
463 | # Add a toolbar option with the 'git clone url' and an | |
464 | # option to display all tags. | |
465 | $feature{'actions'}{'default'} = [ | |
466 | ('clone url', 'git://git.subgeniuskitty.com/%n', 'summary'), | |
467 | ('tags', 'https://git.subgeniuskitty.com/%n/tags', 'summary') | |
468 | ]; | |
4ccc706c AT |
469 | |
470 | # Category name is read from .git/category, in the same manner as .git/description. | |
471 | $projects_list_group_categories = 1; | |
472 | $project_list_default_category = "misc"; | |
473 | ||
474 | # Needed for displaying README files. | |
475 | $prevent_xss = 0; | |
476 | ||
477 | # Enable syntax highlighting. | |
478 | $feature{'highlight'}{'default'} = [1]; | |
479 | ||
480 | ################################################################################ | |
481 | ||
482 | # Enable blame, pickaxe search, snapshop, search, and grep | |
483 | # support, but still allow individual projects to turn them off. | |
484 | # These are features that users can use to interact with your Git trees. They | |
485 | # consume some CPU whenever a user uses them, so you can turn them off if you | |
486 | # need to. Note that the 'override' option means that you can override the | |
487 | # setting on a per-repository basis. | |
488 | $feature{'blame'}{'default'} = [1]; | |
489 | $feature{'blame'}{'override'} = [1]; | |
490 | ||
491 | $feature{'pickaxe'}{'default'} = [1]; | |
492 | $feature{'pickaxe'}{'override'} = [1]; | |
493 | ||
494 | $feature{'snapshot'}{'default'} = [1]; | |
495 | $feature{'snapshot'}{'override'} = [1]; | |
496 | ||
497 | $feature{'search'}{'default'} = [1]; | |
498 | ||
499 | $feature{'grep'}{'default'} = [1]; | |
500 | $feature{'grep'}{'override'} = [1]; | |
501 | ||
502 | Create the directory `/srv/gitweb_cache`. It should be readable by the web | |
503 | server (`www-data`), but owned by `ataylor:ataylor` so that simple scripts like | |
504 | the following can make repositories public/private. | |
505 | ||
506 | #!/usr/local/bin/bash | |
507 | # | |
508 | # Usage: sgkgit-make-public project_name | |
509 | # Make a repo accessible through gitweb and git-daemon. | |
510 | ||
511 | if [ "$#" -ne 1 ]; then | |
512 | echo "Must specify repo name as only parameter." | |
513 | exit 2 | |
514 | fi | |
515 | ||
516 | read -p "Enter a category name: " category | |
517 | read -p "Enter a description: " description | |
518 | ||
519 | echo "You entered:" | |
520 | printf "\tCategory: $category \n" | |
521 | printf "\tDescription: $description \n" | |
522 | read -p "Confirm (y/n)?: " confirm | |
523 | ||
524 | if [ "$confirm" == "y" ]; then | |
525 | ssh ataylor@git.subgeniuskitty.com "cd /srv/gitweb_cache && rm -rf $@ && git clone /srv/git/$@" | |
526 | ssh ataylor@git.subgeniuskitty.com "cd /srv/git && \ | |
527 | printf '#!/usr/bin/bash\ncd /srv/gitweb_cache/$@\ngit --git-dir=.git pull\n' > \ | |
528 | /srv/git/$@/hooks/post-update && chmod +x /srv/git/$@/hooks/post-update" | |
529 | ssh ataylor@git.subgeniuskitty.com "echo \"$category\" > /srv/gitweb_cache/$@/.git/category" | |
530 | ssh ataylor@git.subgeniuskitty.com "echo \"$description\" > /srv/gitweb_cache/$@/.git/description" | |
531 | fi | |
532 | ||
533 | In addition to cloning the git repo into `/srv/gitweb_cache` from the private, | |
534 | SSH-only collection of repositories in `/srv/git`, this also creates a | |
535 | `post-update` hook in the bare repo in `/srv/git` to ensure that gitweb's cache | |
536 | is updated every time a push is made via SSH to the private repo. | |
537 | ||
538 | This script also sets the `.git/description` and `.git/category` files needed | |
539 | by gitweb for displays like the project summary page. These are not under | |
540 | version control and may be directly edited to change what is displayed in | |
541 | gitweb. | |
542 | ||
543 | We can remove the public cache, making the repo private-only as shown in this | |
544 | script. | |
545 | ||
546 | #!/usr/local/bin/bash | |
547 | # | |
548 | # Usage: sgkgit-make-private project_name | |
549 | # Make a repo inaccessible through gitweb and git-daemon. | |
550 | ||
551 | if [ "$#" -ne 1 ]; then | |
552 | echo "Must specify repo name as only parameter." | |
553 | exit 2 | |
554 | fi | |
555 | ||
556 | ssh ataylor@git.subgeniuskitty.com "rm -rf /srv/gitweb_cache/$@ && rm /srv/git/$@/hooks/post-update" | |
557 | ||
558 | Any repos made private/public via this method are immediately reflected in | |
559 | `gitweb` and `git-daemon`. | |
560 | ||
561 | ||
562 | ## Read-Only: Git Daemon ## | |
563 | ||
564 | Since `git` was already installed, simply create a new service profile in | |
565 | `/etc/systemd/system/git-daemon.service`. | |
566 | ||
567 | [Unit] | |
568 | Description=Start Git Daemon | |
569 | ||
570 | [Service] | |
571 | ExecStart=/usr/bin/git daemon --export-all --reuseaddr --base-path=/srv/gitweb_cache/ /srv/gitweb_cache/ | |
572 | ||
573 | Restart=always | |
574 | RestartSec=500ms | |
575 | ||
576 | StandardOutput=syslog | |
577 | StandardError=syslog | |
578 | SyslogIdentifier=git-daemon | |
579 | ||
580 | User=ataylor | |
581 | Group=ataylor | |
582 | ||
583 | [Install] | |
584 | WantedBy=multi-user.target | |
585 | ||
586 | Then start the service with `systemctl daemon-reload` and `systemctl start | |
587 | git-daemon`. Verify functionality before enabling daemon-autostart with | |
588 | `systemctl enable git-daemon`. | |
589 | ||
590 | The `--export-all` flag tells `git-daemon` to export all repositories located | |
591 | at the specified path, regardless of the presence (or lack) of the file | |
592 | `.git/git-daemon-export-ok` in the individual repository. We do this because | |
593 | only public repos are checked out to this folder. All private repos are kept | |
594 | entirely elsewhere. | |
595 | ||
596 | The directory `/srv/gitweb_cache` should have already been created when | |
597 | installing gitweb. If not, go read those instructions. | |
598 | ||
599 | A repository located at `/srv/gitweb_cache/repo_name` may be cloned through | |
600 | `git-daemon` at | |
601 | [git://git.subgeniuskitty.com/repo_name](git://git.subgeniuskitty.com/repo_name) | |
602 | with `git clone`. | |
603 | ||
604 | ||
605 | # Mail Server # | |
606 | ||
607 | TODO | |
608 | ||
609 | TODO | |
610 | ||
611 | TODO | |
612 | ||
613 | TODO | |
614 | ||
615 | TODO | |
616 | ||
617 | TODO | |
618 | ||
619 | TODO | |
620 | ||
621 | TODO | |
622 |