diff options
| -rw-r--r-- | blog/git_server.html | 135 | ||||
| -rw-r--r-- | blog_src/git_server.md | 174 | ||||
| -rwxr-xr-x | generate-blog | 6 | ||||
| -rw-r--r-- | index.html | 2 |
4 files changed, 313 insertions, 4 deletions
diff --git a/blog/git_server.html b/blog/git_server.html new file mode 100644 index 0000000..49a9566 --- /dev/null +++ b/blog/git_server.html @@ -0,0 +1,135 @@ +<!DOCTYPE html> + +<html> + <head> + <title>cacharle</title> + <link rel="stylesheet" type="text/css" href="../style.css"/> + <meta charset="utf-8"/> + <link rel="icon" type="image/png" href="../favicon.png" /> + </head> + + <body> + <div id="page-wrapper"> + <!--BLOG--> +<h1 id="how-to-make-your-own-git-serverwebsite">How to make your own git server/website</h1> +<h2 id="server-setup">Server setup</h2> +<p>We’re going to create a <code>git</code> user and group, will be used for accessing our git repositories without needing to be root.</p> +<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="ex">useradd</span> -m git</span> +<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="fu">mkdir</span> /srv/git</span> +<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a><span class="fu">chown</span> git:git /srv/git</span></code></pre></div> +<p>The repositories will be stored as bare, this mean that we will only store the <code>.git</code> folder to save space.</p> +<blockquote> +<p>To create a bare repo: <code>git init --bare</code></p> +</blockquote> +<blockquote> +<p>To clone a repo as bare: <code>git clone bare <location></code></p> +</blockquote> +<p>You can either add a password for the git user or put your ssh public key in <code>/home/git/.ssh/authentication_keys</code> and disable password authentication for ssh.</p> +<p>You can now clone from your server with <code>git clone git@<hostname>:/srv/git/<reponame></code></p> +<h2 id="better-server-interaction-with-git-shell">Better server interaction with git-shell</h2> +<p>Permit the git user to have a regular shell can be a security issue, we would like that to restrict him to a few action, like creating/deleting a repository, importing a repository, listing the repo currently stored</p> +<p>Make the git-shell a valid shell <code>echo $(which git-shell) >> /etc/shells</code></p> +<p>Change the shell of the git user <code>chsh -s $(which git-shell) git</code></p> +<p>If you try to ssh as the git user, you will be greeted with something along the line of:</p> +<pre><code>fatal: Interactive git shell is not enabled. +hint: ~/git-shell-commands should exist and have read and execute access. +Connection to <host> closed.</code></pre> +<p>As suggested by the hint we have to create the directory <code>/home/git/git-shell-commands</code> and put the commands (executable) that the git user is allowed to execute in.</p> +<p>Here is a script to create a repo:</p> +<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="co">#!/bin/sh</span></span> +<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a><span class="bu">[</span> <span class="va">$#</span> <span class="ot">-ne</span> 1<span class="bu"> ]</span> <span class="kw">&&</span> <span class="bu">echo</span> <span class="st">"Usage: </span><span class="va">$0</span><span class="st"> name"</span> <span class="kw">&&</span> <span class="bu">exit</span> 1</span> +<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a><span class="va">repo_path=</span><span class="st">"/srv/git/</span><span class="va">$1</span><span class="st">.git"</span></span> +<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a><span class="bu">[</span> <span class="ot">-d</span> <span class="st">"</span><span class="va">$repo_path</span><span class="st">"</span><span class="bu"> ]</span> <span class="kw">&&</span> <span class="bu">echo</span> <span class="st">"</span><span class="va">$0</span><span class="st">: Error: </span><span class="va">$repo_path</span><span class="st"> already exist"</span> <span class="kw">&&</span> <span class="bu">exit</span> 2</span> +<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a><span class="fu">mkdir</span> <span class="st">"</span><span class="va">$repo_path</span><span class="st">"</span></span> +<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a><span class="fu">git</span> -C <span class="st">"</span><span class="va">$repo_path</span><span class="st">"</span> init --bare</span></code></pre></div> +<p>Put it under <code>git-shell-commands/create</code> and make it executable then try to ssh as the git user once again.</p> +<p>You should have a prompt like <code>git></code>, you can call the <code>create</code> command with a repo name as the first argument and it should create a new repository for you.</p> +<h2 id="allow-anyone-to-clone-with-git-daemon">Allow anyone to clone with git-daemon</h2> +<p>The git daemon will allow annone to clone your repos with something like <code>git clone git://<host>/<repo></code></p> +<p><code>git daemon --reuseaddr --base-path=/srv/git/ /srv/git/</code> and that’s it</p> +<p>You should make it a service in your service supervisor, example with systemctl:</p> +<pre><code>[Unit] +Description=Start Git Daemon +[Service] +ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ +Restart=always +RestartSec=500ms +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=git-daemon +User=git +Group=git +[Install] +WantedBy=multi-user.target</code></pre> +<p>Put it in <code>/etc/systemctl/system/git-daemon.service</code> and run <code>systemctl enable git-daemon</code> then <code>systemctl start git-daemon</code>.</p> +<h3 id="publicprivate-repo">Public/private repo</h3> +<p>You may want to introduce a distiction of which repo is public and which is private</p> +<p>A simple way to do this is by creating a <code>public</code> directory in <code>/srv/git</code> which will contain symbolic link to the repo in <code>/srv/git</code></p> +<pre><code>/srv/git +|- foo.git +|- bar.git +|- qux.git +|- public + |- foo.git -> /srv/git/foo.git + |- bar.git -> /srv/git/bar.git</code></pre> +<p>You can change the git daemon to only serve the public repositories <code>git daemon --reuseaddr --base-path=/srv/git/public /srv/git/public</code></p> +<h2 id="generate-a-static-website">Generate a static website</h2> +<p>Here we will create a site that look’s like <a href="https://git.suckless.org">this</a> with <a href="https://nginx.org">nginx</a>, <a href="https://git.codemadness.org/stagit/">stagit</a> and a few scripts.</p> +<p>If you don’t like the minimalistic appearence of the site, <a href="https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Web_Interfaces">here</a> is a list of alternative.</p> +<p>Install nginx (on Debian based distro): <code>apt install nginx</code></p> +<p>Create a basic configuration file for your site:</p> +<pre><code>server { + root /var/www/git; + index index.html index.htm; + + server_name git.<hostname> www.git.<hostname>; + + location / { + try_files $uri $uri/ =404; + } +}</code></pre> +<p>It’s a convention to put it in a <code>git.</code> subdomain. <code>systemctl enable nginx && systemctl start nginx</code></p> +<p>Install stagit:</p> +<pre><code>git clone git://git.codemadness.org/stagit +cd stagit +make +make install</code></pre> +<p>To generate a static page for a repo <code>stagit /path/to/repo</code>. To generate an index for multiple repositories <code>stagit-index repo1 repo2 repo3 > index.html</code></p> +<p>Here is a script to generate a site for all repo in <code>/srv/git/public</code></p> +<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="co">#!/bin/sh</span></span> +<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a></span> +<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a><span class="va">repos=$(</span><span class="fu">find</span> /srv/git/public/ -type l<span class="va">)</span></span> +<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a><span class="va">current=$(</span><span class="bu">pwd</span><span class="va">)</span></span> +<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a></span> +<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a><span class="kw">for</span> <span class="ex">repo</span> in <span class="va">$repos</span><span class="kw">;</span> <span class="kw">do</span></span> +<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a> <span class="va">repo_name=$(</span><span class="fu">basename</span> <span class="st">"</span><span class="va">$repo</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">'s/\.git//'</span><span class="va">)</span></span> +<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a> <span class="va">repo_static_path=</span><span class="st">"/var/www/git/</span><span class="va">$repo_name</span><span class="st">"</span></span> +<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a> <span class="fu">mkdir</span> -p <span class="st">"</span><span class="va">$repo_static_path</span><span class="st">"</span></span> +<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a> <span class="bu">cd</span> <span class="st">"</span><span class="va">$repo_static_path</span><span class="st">"</span> <span class="kw">||</span> <span class="bu">exit</span> 1</span> +<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a> <span class="bu">echo</span> <span class="st">"git://cacharle.xyz/</span><span class="va">$repo_name</span><span class="st">"</span> <span class="op">></span> <span class="st">"</span><span class="va">$repo</span><span class="st">/url"</span></span> +<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a> <span class="ex">stagit</span> <span class="st">"</span><span class="va">$repo</span><span class="st">"</span></span> +<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a> <span class="fu">ln</span> -sf <span class="st">"</span><span class="va">$repo_static_path</span><span class="st">/log.html"</span> <span class="st">"</span><span class="va">$repo_static_path</span><span class="st">/index.html"</span></span> +<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a> <span class="bu">echo</span> <span class="st">"Generated </span><span class="va">$repo_static_path</span><span class="st">"</span></span> +<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a><span class="kw">done</span></span> +<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a></span> +<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Creating index"</span></span> +<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a><span class="ex">stagit-index</span> <span class="va">$repos</span> <span class="op">></span> /var/www/git/index.html</span> +<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a></span> +<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$current</span><span class="st">"</span> <span class="kw">||</span> <span class="bu">exit</span> 1</span> +<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a><span class="fu">chown</span> -R git:git /srv/git</span></code></pre></div> +<p>There is more smart ways to handle this to rebuild the webpages each time someone pushes to the repo with <a href="https://git.codemadness.org/stagit/file/README.html#l92">git hooks</a>.</p> +<h2 id="sources">Sources</h2> +<ul> +<li><a href="https://www.youtube.com/watch?v=ju9loeXNVW0">Setting up *Your Own* Git Server</a></li> +<li><a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server">Git book - setting up the server</a></li> +<li><a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Git-Daemon">Git book - git daemon</a></li> +<li><a href="https://git.codemadness.org/stagit/">stagit - Static website generator for git repository</a></li> +<li><a href="https://git-scm.com/docs/git-shell.html">git-shell man</a></li> +</ul> + </div> + + <footer> + <!--TODO--> + <footer> + </body> +</html> diff --git a/blog_src/git_server.md b/blog_src/git_server.md new file mode 100644 index 0000000..4fc5505 --- /dev/null +++ b/blog_src/git_server.md @@ -0,0 +1,174 @@ +# How to make your own git server/website + +## Server setup + +We're going to create a `git` user and group, will be used for accessing our git repositories without needing to be root. + +```sh +useradd -m git +mkdir /srv/git +chown git:git /srv/git +``` + +The repositories will be stored as bare, this mean that we will only store the `.git` folder to save space. + +>To create a bare repo: `git init --bare` + +>To clone a repo as bare: `git clone bare <location>` + +You can either add a password for the git user or put your ssh public key in `/home/git/.ssh/authentication_keys` and disable password authentication for ssh. + +You can now clone from your server with `git clone git@<hostname>:/srv/git/<reponame>` + +## Better server interaction with git-shell + +Permit the git user to have a regular shell can be a security issue, +we would like that to restrict him to a few action, +like creating/deleting a repository, importing a repository, listing the repo currently stored + +Make the git-shell a valid shell `echo $(which git-shell) >> /etc/shells` + +Change the shell of the git user `chsh -s $(which git-shell) git` + +If you try to ssh as the git user, you will be greeted with something along the line of: + +``` +fatal: Interactive git shell is not enabled. +hint: ~/git-shell-commands should exist and have read and execute access. +Connection to <host> closed. +``` + +As suggested by the hint we have to create the directory `/home/git/git-shell-commands` and put the commands (executable) that the git user is allowed to execute in. + +Here is a script to create a repo: + +```sh +#!/bin/sh +[ $# -ne 1 ] && echo "Usage: $0 name" && exit 1 +repo_path="/srv/git/$1.git" +[ -d "$repo_path" ] && echo "$0: Error: $repo_path already exist" && exit 2 +mkdir "$repo_path" +git -C "$repo_path" init --bare +``` + +Put it under `git-shell-commands/create` and make it executable then try to ssh as the git user once again. + +You should have a prompt like `git> `, you can call the `create` command with a repo name as the first argument and it should create a new repository for you. + +## Allow anyone to clone with git-daemon + +The git daemon will allow annone to clone your repos with something like `git clone git://<host>/<repo>` + +`git daemon --reuseaddr --base-path=/srv/git/ /srv/git/` and that's it + +You should make it a service in your service supervisor, example with systemctl: + +``` +[Unit] +Description=Start Git Daemon +[Service] +ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ +Restart=always +RestartSec=500ms +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=git-daemon +User=git +Group=git +[Install] +WantedBy=multi-user.target +``` + +Put it in `/etc/systemctl/system/git-daemon.service` and run `systemctl enable git-daemon` then `systemctl start git-daemon`. + +### Public/private repo + +You may want to introduce a distiction of which repo is public and which is private + +A simple way to do this is by creating a `public` directory in `/srv/git` which will contain symbolic link to the repo in `/srv/git` + +``` +/srv/git +|- foo.git +|- bar.git +|- qux.git +|- public + |- foo.git -> /srv/git/foo.git + |- bar.git -> /srv/git/bar.git +``` + +You can change the git daemon to only serve the public repositories `git daemon --reuseaddr --base-path=/srv/git/public /srv/git/public` + +## Generate a static website + +Here we will create a site that look's like [this](https://git.suckless.org) with [nginx](https://nginx.org), [stagit](https://git.codemadness.org/stagit/) and a few scripts. + +If you don't like the minimalistic appearence of the site, [here](https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Web_Interfaces) is a list of alternative. + +Install nginx (on Debian based distro): `apt install nginx` + +Create a basic configuration file for your site: + +``` +server { + root /var/www/git; + index index.html index.htm; + + server_name git.<hostname> www.git.<hostname>; + + location / { + try_files $uri $uri/ =404; + } +} +``` + +It's a convention to put it in a `git.` subdomain. +`systemctl enable nginx && systemctl start nginx` + +Install stagit: + +``` +git clone git://git.codemadness.org/stagit +cd stagit +make +make install +``` + +To generate a static page for a repo `stagit /path/to/repo`. +To generate an index for multiple repositories `stagit-index repo1 repo2 repo3 > index.html` + +Here is a script to generate a site for all repo in `/srv/git/public` + +```sh +#!/bin/sh + +repos=$(find /srv/git/public/ -type l) +current=$(pwd) + +for repo in $repos; do + repo_name=$(basename "$repo" | sed 's/\.git//') + repo_static_path="/var/www/git/$repo_name" + mkdir -p "$repo_static_path" + cd "$repo_static_path" || exit 1 + echo "git://cacharle.xyz/$repo_name" > "$repo/url" + stagit "$repo" + ln -sf "$repo_static_path/log.html" "$repo_static_path/index.html" + echo "Generated $repo_static_path" +done + +echo "Creating index" +stagit-index $repos > /var/www/git/index.html + +cd "$current" || exit 1 +chown -R git:git /srv/git +``` + +There is more smart ways to handle this to rebuild the webpages each time someone pushes to the repo with [git hooks](https://git.codemadness.org/stagit/file/README.html#l92). + +## Sources + +* [Setting up \*Your Own\* Git Server](https://www.youtube.com/watch?v=ju9loeXNVW0) +* [Git book - setting up the server](https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server) +* [Git book - git daemon](https://git-scm.com/book/en/v2/Git-on-the-Server-Git-Daemon) +* [stagit - Static website generator for git repository](https://git.codemadness.org/stagit/) +* [git-shell man](https://git-scm.com/docs/git-shell.html) diff --git a/generate-blog b/generate-blog index 8694b74..6d3add1 100755 --- a/generate-blog +++ b/generate-blog @@ -3,12 +3,12 @@ # Put your articles in a blog_src directory # Depends on pandoc for markdown to html convertion -[ ! -d blog_src ] || [ -z $(ls blog_src) ] && exit 1 -mkdir -p blog - cp -vf index.template.html index.html rm -vf blog/* +[ ! -d blog_src ] || [ -z "$(ls blog_src)" ] && exit 1 +mkdir -p blog + for article_path in blog_src/*.md do article_dst_path=$(echo "$article_path" | sed 's/blog_src/blog/' | sed 's/\.md/.html/') @@ -19,7 +19,7 @@ <h2>Blog articles</h2> <ul> <!--BLOGINDEX--> -<li><a href="blog/yo.html"> yo</a></li> +<li><a href="blog/git_server.html"> How to make your own git server/website</a></li> </ul> <h2>Links</h2> |
