grim/hgkeeper

c47e4554fa47
Parents 61b4f876b057
Children 5b6ad1b98031
Move all of the documentation to mkdocs.

There's still a bit to do, but this is much better than the single readme file
ever was.
--- a/.hgignore Mon Mar 07 02:26:05 2022 -0600
+++ b/.hgignore Wed Mar 23 13:28:31 2022 -0500
@@ -1,4 +1,5 @@
syntax: regexp
+^docs\/site\/
^host-keys\/
^hgkeeper$
^setup\/resources\.go$
--- a/README.md Mon Mar 07 02:26:05 2022 -0600
+++ b/README.md Wed Mar 23 13:28:31 2022 -0500
@@ -9,405 +9,26 @@
It was originally designed to be run in a container but recently support has
been added to run it from an existing openssh-server.
+## Documentation
+
+You can find the full documentation
+[here](https://docs.imfreedom.org/hgkeeper/).
+
## License
HGKeeper is licensed under the GNU AFFERO GENERAL PUBLIC LICENSE version 3.
## Status
-This project is brand new and only lightly tested. If you find issues, or are
+This project has been used for awhile in production environment, but every evironment is different. So, if you find issues, or are
looking for ways to help, please check out our
[issue tracker](https://issues.imfreedom.org/issues/HGKEEPER?u=1).
## Building
-You can build hgkeeper with the following commands:
+You can build hgkeeper with the following command:
```
$ go build
```
-## Getting Started
-
-The initial setup of HGKeeper has a few steps.
-
-### SSH Host Keys
-
-Since HGKeeper provides an SSH server you will need to generate host keys for
-it if you are going to use it. You can skip the SSH server by passing
-`--disable-ssh` or setting the `HGK_DISABLE_SSH` environment variable to `true`.
-This is useful if you just want to provide read only repositories.
-
-You can generate SSH host keys for whatever type you like, but rsa will cover
-just about everyone. That said, a lot of people prefer to use ed25519 as well.
-
-By default the SSH host keys will be looked for in the directory `host-keys` in
-the current working directory of HGKeeper. This can be changed with the
-`--ssh-host-keys-path` or `-H` command line arguments to hgkeeper.
-
-This directory will be read and files in it will attempt to be loaded into the
-server.
-
-To generate a host key you can use the following commands, note that you can
-create other types via the `-t` option, but you should read the `ssh-keygen`
-documentation as other options are available for each type.
-
-```
-$ ssh-keygen -t rsa -b 4096 -o host-keys/ssh_host_rsa_key
-$ ssh-keygen -t ed25519 -o host-keys/ssh_host_ed25519_key
-```
-
-### Create the hgkeeper repo
-
-Before you can run the server we need to create the `hgkeeper` admin
-repository. This can be done via `hgkeeper setup`. You will need to pass the
-arguments `--admin-username` which is the username of the admin user, as well
-as `--admin-pubkey` which is the path to the SSH public key for the new admin
-user. By default this will create a new repository under `repos/hgkeeper`.
-There are some additional options which you can discover via
-`hgkeeper setup --help`.
-
-## Usage
-
-HGKeeper has a couple of modes of operation but `serve` is the main mode.
-
-### setup
-
-The `setup` command is used to bootstrap HGKeeper. It will create the
-directory for the repositories as well as the `hgkeeper` repository.
-
-After initial setup, please make sure to read the `README.md` in the `hgkeeper`
-admin repository that was created, as it details how access control works.
-
-### serve
-
-The `serve` command is the main mode of operation which is to provide access to
-the repositories.
-
-You can optionally disable either one of the HGWeb or SSH servers to limit
-resources or just disable the portions you don't need. However, the HTTP server
-will always be active as it contains a health endpoint at `/hgk/health` and
-could be used for integration with OpenSSH Server via the `--external-hostname`
-argument.
-
-For example, say you don't need public access or the HGWeb interface at all,
-you can disable it by passing `--disable-hgweb` to the `serve` command or by
-setting the `HGK_DISABLE_HGWEB` environment variable to `true`.
-
-Likewise, if you just want to serve up read only repositories over http you can
-disable the SSH server by passing `--disable-ssh` to the `serve` command or by
-setting the `HGK_DISABLE_SSH` environment variable to `true`.
-
-The `--disable-hgweb` and `--disable-ssh` options are mutually exclusive and
-passing both will stop HGKeeper from starting.
-
-The `serve` command also has options to tell HGKeeper how it can be accessed
-remotely. This is useful when integrating it with OpenSSH Server. These options
-are `--external-hostname` and `--external-port`. `--external-hostname` can be
-a hostname or an IP address, but it should be the address that you're using
-to access HGKeeper. Likewise, `--external-port` is the external port that will
-get you to HGKeeper. It has a default value of `22222`.
-
-### authorized-keys
-
-The `authorized-keys` command is used when itegrating with OpenSSH on the same
-host as HGKeeper. It takes a single argument as the SHA256 fingerprint of the
-an SSH public key. If that key is known to HGKeeper, it will output an
-`authorized_keys` text that OpenSSH can use to continue the HG operation.
-
-### once
-
-The `once` command is used in conjunction with the above mentioned
-`authorized-keys` command. It is the command that HGKeeper specifies that
-Open SSH should use to continue the SSH operations and is not useful in any
-other way.
-
-## Access Control
-
-Access control is defined in the `hgkeeper` admin repository that is created
-via the `hgkeeper setup` command. It is implemented via
-[casbin](https://casbin.org) using the RBAC with deny-override model as a
-base. More information can be found in the [files](setup/resources/)
-that are placed in the `hgkeeper` admin repository.
-
-## Running HGKeeper
-
-There are multiple ways to run HGKeeper. It can be ran in a container, as a
-standalone server directly on a host, or executed on demand by OpenSSH.
-
-Both running in a container and running as a standalone can also be integrated
-with OpenSSH as well.
-
-## Running in a Container
-
-HGKeeper is available on docker hub under
-[rwgrim/hgkeeper](https://hub.docker.com/r/rwgrim/hgkeeper) and is updated via
-CI.
-
-Just like all modes of operation, running in the container is going to require
-an `hgkeeper` admin repository and at least one SSH host key.
-
-First we will create the HGKeeper admin repository. We will use the normal
-HGKeeper container with an overridden command to run the setup. An extra step
-to this is that you will need to volume mount in a file containing the public
-key of the initial administrator of this instance. In the following example, we
-assume that the key is in `~/.ssh/id_rsa.pub`.
-
-Also, since this container is just used for initialization of files on the
-host, we're passing the `--rm` flag to make sure it's deleted when done.
-
-We can now run the initialization setup that follows.
-
-```
-docker run --rm \
- -v $(pwd)/repos:/repos \
- -v ~/.ssh/id_rsa.pub:/admin-pubkey:ro \
- -e HGK_ADMIN_USERNAME=my_username \
- -e HGK_ADMIN_PUBKEY=/admin-pubkey \
- -e HGK_REPOS_PATH=/repos \
- docker.io/rwgrim/hgkeeper:latest \
- hgkeeper setup
-```
-
-Once this step is done you should now have a `repos` directory in your current
-working directory and it should have a brand new `hgkeeper` admin repository
-in it. These repositories are HGKeeper's copies of them, you should not modify
-them directly and should be using the SSH capabilities of HGKeeper to push/pull
-to them.
-
-For the rest of these instructions we are going to assume that you have your
-SSH host keys in a directory named `host-keys` in the current working
-directory.
-
-The following example uses the same assumptions as the setup container above,
-but it is also going to expose the container on the host's network interface.
-The following example runs the container in the background, gives it a name of
-`hgkeeper`, and sets it to always restart. If you're just doing testing, you
-will probably want to remove the `-d` (background), `--name hgkeeper` (name),
-and `--restart=always` options.
-
-```
-docker run -d --name hgkeeper \
- --restart=always \
- -v $(pwd)/host-keys:/host-keys:ro \
- -v $(pwd)/repos:/repos \
- -e HGK_SSH_HOST_KEYS=/host-keys \
- -e HGK_REPOS_PATH=/repos \
- -p 8080:8080 \
- -p 22222:22222 \
- docker.io/rwgrim/hgkeeper:latest \
- hgkeeper serve
-```
-
-If you would like to integrate this container with OpenSSH server, please see
-the `Integrating With OpenSSH Server` section below.
-
-If you want to integrate this container with an existing OpenSSH server and
-keep HGKeeper only on the loopback device, you can do that by adding the
-`HGK_EXTERNAL_HOSTNAME` and `HGK_EXTERNAL_PORT` environment variables. This
-will enable an `/hgk/authorized_keys` HTTP endpoint that we can tell OpenSSH
-server to use. We'll also change the port forwards from any interface on the
-host to just the loopback device. To do this, you'd change the container
-command to the following:
-
-```
-docker run -d --name hgkeeper \
- --restart=always \
- -v $(pwd)/host-keys:/host-keys:ro \
- -v $(pwd)/repos:/repos \
- -e HGK_SSH_HOST_KEYS=/host-keys \
- -e HGK_REPOS_PATH=/repos \
- -e HGK_EXTERNAL_HOSTNAME=<hostname or ip address> \
- -e HGK_EXTERNAL_PORT=22222 \
- -p 127.0.0.1:8080:8080 \
- -p 127.0.0.1:22222:22222 \
- docker.io/rwgrim/hgkeeper:latest \
- hgkeeper serve
-```
-
-The `<hostname or ip address>` is the hostname or IP address of the host where
-the container is running, and the value of `HGK_EXTERNAL_PORT` needs to match
-the host port number specified in the `-p` argument for the SSH port which is
-22222 in this example.
-
-To configure the OpenSSH server portion you'll need to make sure that the host
-has the `ssh` client as well as `curl` installed. Then you can add the
-following block to `/etc/ssh/sshd_config` replacing `<hostname>` and `<port>`
-with the hostname of the machine running the container and the HTTP port that
-was forwarded for the container. In example above, that was port `8080`.
-
-```
-Match User hg
- AuthorizedKeysCommand curl -q http://<hostname>:<port>/hgk/authorized_keys?fp=%f
- AuthorizedKeysCommandUser hg
-```
-
-Once this change has been made, you need to reload OpenSSH server, but then you
-should be able to access the HGKeeper repositories by using
-`ssh://hg@<hostname>:<port>/<repository>`.
-
-And that's it!
-
-Of course, you'll probably want to add some more users. To find out how to do
-that, be sure to read the `README.md` in the `hgkeeper` admin repository.
-
-## Running Locally
-
-We do not currently provide any packages or startup scripts for HGKeeper, but
-to get started it is recommended that you create an `hg` user and store
-everything in that user's home directory.
-
-For most Linux distributions, you can create the `hg` user with the following
-command:
-
-```
-useradd --home-dir /var/lib/hg --create-home --system --shell /usr/sbin/nologin
-```
-
-To make life easier we're going to run the setup command as the `hg` user, but
-since the `hg` user doesn't have a shell we have to tell the `su` command which
-shell to use. So to get started type the following command:
-
-```
-su -s /bin/bash hg
-cd ~
-whoami
-```
-
-You should now see a bash prompt with the output of the `whoami` command saying
-that you are the `hg` user. If not, please review these steps and try again.
-
-If you did see the `hg` username output, you can follow the steps in
-`SSH Host Keys` and `Create the hgkeeper repo`.
-
-Once the SSH host keys and the `hgkeeper` admin repository are created, you
-can run HGKeeper with the `hgkeeper serve` command. There are some other
-options that are available so be sure to check out `hgkeeper serve --help`.
-
-If you would like to integrate this with an existing OpenSSH server, see the
-`Integrating with OpenSSH Server` section below.
-
-## Integrating with OpenSSH Server
-
-There are a two different ways to integrate HGKeeper with OpenSSH Server and
-some of the steps vary across operating systems. If you run into a case where
-these instructions do not work for you, please reach out via the issue tracker
-so we can help you and fix the documentation.
-
-The two modes of operation are `serve` and `run once`.
-
-`serve` mode can include the normal container setup described above, which
-would integrate with OpenSSH Server the same way as running HGKeeper locally.
-Running HGKeeper in `serve` mode means that you can also use the HTTP portion
-of it as the HTTP portion is required for integrating the serve mode with
-OpenSSH.
-
-Run once mode, uses the built-in mechanisms of OpenSSH Server to run HGKeeper
-when someone connects. This method means that the HTTP portion of HGKeeper will
-not be available.
-
-### Creating the hg user
-
-When it comes to integrating with OpenSSH server you need to create a user that
-will run interact with HGKeeper during SSH connections and in `run once` mode
-own the repositories on disk. This user can be named whatever you like, but for
-the purposes of this documentation we will be naming the user `hg`.
-
-Regardless of your mode of operation, you will need to create this user on the
-OpenSSH Server's host operating system. In the documentation for running
-locally above, we already created this user.
-
-For most Linux distributions, you can create the `hg` user with the following
-command:
-
-```
-useradd --home-dir /var/lib/hg --create-home --system --shell /usr/sbin/nologin
-```
-
-### Setup HGKeeper
-
-This step is only necessary for `run once` mode.
-
-To get HGKeeper fully running, you will need to run `hgkeeper setup` to create
-the `hgkeeper` admin repository as well as the initial admin user. Once this
-repository is created, make sure it and it's parent directory is owned by the
-`hg` user and that the `hg` user has write permission.
-
-### Installing HGKeeper
-
-This step is only necessary for `run once` mode.
-
-OpenSSH server has some very specific requirements for calling applications
-directly. These requirements are that the executable as well as all of the
-directories leading up to the executable must be owned by root and not
-writeable by the group or other users. To deal with this, we will be
-installing HGKeeper into `/usr/local/bin`. This directory should fulfill all
-of the those requirements. So just `sudo cp hgkeeper /usr/local/bin/` and
-make sure that it is owned by `root` with a file mode of `755`.
-
-### Configuring OpenSSH Server
-
-The OpenSSH configuration is actually quite easy, you just need to drop the
-one of the following snippet into `/etc/ssh/sshd_config` depending on your
-mode of operation. Of course, if you customized the install location or
-username you'll have to adjust that in the snippets below.
-
-You may be able to use `/etc/ssh/sshd_config.d/hgkeeper.conf` but in our
-testing on Debian unstable we were unable to get it working properly.
-
-For `run once` mode, you can use the following snippet, but note that the value
-for `--repos-path` needs to be the absolute path to your repositories.
-
-```
-Match User hg
- AuthorizedKeysCommand /usr/local/bin/hgkeeper --repos-path=<path to your repositories> authorized-keys %f
- AuthorizedKeysCommandUser hg
-```
-
-For serve mode you need to know the external hostname and port number for HTTP
-for HGKeeper. Once you have that info, you can use the following snippet.
-
-```
-Match User hg
- AuthorizedKeysCommand /usr/bin/curl -q http://<external-hostname>:<external-http-port>/hgk/authorized_keys?fp=%f
- AuthorizedKeysCommandUser hg
-```
-
-Once you've created the file, you'll need to reload OpenSSH Server. This is
-usually done via `service ssh reload` but may vary based on your operating
-system.
-
-Once you've reloaded OpenSSH Server you should be able to clone the `hgkeeper`
-admin repository with `hg clone ssh://hg@yourhostname/hgkeeper` as long as the
-machine you're cloning from has the private key that you added as your initial
-admin user.
-
-## Creating Repositories
-
-Creating a new repository in HGKeeper is just the same as using Mercurial over
-SSH. That is, you can use the `hg init` command with a path to HGKeeper. As
-long as you have init permission for the path `HGKeeper` will create an empty
-repository for you.
-
-For example, if you wanted to create a new repository named
-`myteam/new-project-1`, you would do so with
-`hg init ssh://hg@my-hgkeeper-domain/myteam/new-project-1`. If there were no
-issues, the command will exit without error and you are now free to clone it
-with `hg clone ssh://hg@my-hgkeeper-domain/myteam/new-project-1`.
-
-## Known Errata
-
-### no mutual signature algorithm
-
-Fedora 33 disabled `ssh-rsa` by default in openssh-client. This breaks the
-golang `x/crypto/ssh` library. See
-[this bug](https://github.com/golang/go/issues/37278) for more details.
-
-The current work around for this is to add a host block in your ssh client
-configuration to re-enable `ssh-rsa`. See the following example:
-
-```
-Host <hgkeeper hostname>
- PubkeyAcceptedKeyTypes ssh-rsa
-```
-
--- a/convey.yml Mon Mar 07 02:26:05 2022 -0600
+++ b/convey.yml Wed Mar 23 13:28:31 2022 -0500
@@ -30,6 +30,26 @@
type: docker/push
images: ${REGISTRY}/${REPO}:${TAG}
+ docs-clean:
+ type: convey/clean
+ files: site
+
+ docs-import:
+ type: docker/import
+ files: docs:.
+
+ docs-build:
+ type: docker/run
+ image: docker.io/python:3-alpine
+ script:
+ - python3 -m pip install mkdocs mkdocs-include-markdown-plugin
+ - cd ${CONVEY_WORKSPACE}
+ - mkdocs build
+
+ docs-export:
+ type: docker/export
+ files: site:site
+
plans:
default:
stages:
@@ -39,3 +59,11 @@
- tasks: [import, build, login, push]
- tasks: [logout]
run: always
+ docs:
+ stages:
+ - tasks: [docs-clean]
+ - tasks: [docs-import, docs-build, docs-export]
+
+ clean:
+ stages:
+ - tasks: [docs-clean]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/README.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,7 @@
+This documentation gets deployed to
+[docs.imfreedom.org/hgkeeper](https://docs.imfreedom.org/hgkeeper/) via CI.
+
+To build it locally it requires the
+[include-markdown](https://github.com/mondeja/mkdocs-include-markdown-plugin)
+plugin.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/accesscontrol.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,8 @@
+# Access Control
+
+Access control is defined in the `hgkeeper` administration repository. that is
+created via the `hgkeeper setup` command. It is implemented via
+[Casbin](https://casbin.org/) using the RBAC with deny-override model as a
+base.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/commandreference.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,58 @@
+# Command Reference
+
+HGKeeper has a number of sub commands, but `serve` is the most useful one.
+
+## setup
+
+The `setup` command is used to bootstrap HGKeeper. It will create the directory
+for the repositories as well as the `hgkeeper` administration repository.
+
+After initial setup, please make sure to read the `README.md` in the `hgkeeper`
+admin repository that was created as it details how access control works.
+
+## serve
+
+The `serve` command is the main mode of operation which is to provide access to
+the repositories.
+
+You can optionally disable either one of the HGWeb or SSH servers to limit
+resource usage or just disable the portions you don't need. However, the HTTP
+server will always be active as it contains a health endpoint at `/hgk/health`
+and could be used for integration with OpenSSH Server via the
+`--enable-hostname` argument.
+
+For example, say you don't need public access or the HGWeb interface at all,
+you can disable it by passing `--disable-hgweb` to the `serve` command or by
+setting the `HGK_DISABLE_HGWEB` environment variable to `true`.
+
+Likewise, if you just want to serve up read only repositories over HTTP you can
+disable the SSH serve by passing `--disable-ssh` to the `serve` command or by
+setting the `HGK_DISABLE_SSH` environment variable to `true`.
+
+The `--disable-hgweb` and `disable-ssh` options are mutually exclusive and
+passing both will stop HGKeeper from starting.
+
+The `serve` command also has options to tell HGKeeper how it can be accessed
+externally. This is useful when integrating with OpenSSH Server. These options
+are `--external-hostname` and `--external-port`.
+
+`--external-hostname` can be a hostname or IP address, but it needs to be an
+address that your OpenSSH Server can connect to. Likewise, `--external-port`
+is the external port that the OpenSSH Server can reach to connect to HGKeeper's
+SSH server. It has a default value of `22222`.
+
+## authorized-keys
+
+The `authorized-keys` command is used when integrating with OpenSSH server in
+the [on demand](ondemand) mode of operation. It takes a single argument as the
+SHA256 fingerprint of the SSH public key that OpenSSH will provide. If HGKeeper
+knows that key, it will output an `authorized_keys(8)` text that OpenSSH Server
+can use to continue the HG operation.
+
+## once
+
+The `once` command is used in conjunction with the above mentioned
+`authorized-keys` command for [on demand](ondemand) operation. It is the
+command that HGKeeper tells OpenSSH Server to run to continue the SSH
+operations and is not useful in any other way.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/index.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,27 @@
+# About
+
+HGKeeper is a light weight hosting solution for
+[Mercurial](https://www.mercurial-smc.org/) repositories. It provides access
+control for SSH access and provides public HTTP access via
+[hgweb](https://www.mercurial-scm.org/wiki/PublishingRepositories#hgweb).
+
+It was originally designed to be run in [standalone](standalone) mode in a
+container but has recently grown support for working with an existing OpenSSH
+server as well.
+
+# License
+
+HGKeeper is licensed under the
+[GNU AFFERO GENERAL PUBLIC LIECENSE version 3](https://www.gnu.org/licenses/agpl-3.0.en.html).
+
+# Contact
+
+The source code for HGKeeper is of course hosted by an HGKeeper instance at
+[keep.imfreedom.org/grim/hgkeeper](https://keep.imfreedom.org/grim/hgkeeper).
+
+We have an issue tracker which is available at
+[issues.imfreedom.org/issues/HGKEEPER](https://issues.imfreedom.org/issues/HGKEEPER?u=1).
+
+If you are having any other issues, you can reach us on XMPP at
+[hgkeeper@conference.imfreedom.org](xmpp:hgkeeper@conference.imfreedom.org?join).
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/ondemand.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,44 @@
+# On Demand
+
+You can run HGKeeper on demand to integrate it directly with an OpenSSH Server.
+This is accomplished by having a local user on the host, typically named `hg`,
+and telling the OpenSSH server to do something specific when that user logs in.
+
+HGKeeper will also be ran via this user and all of the repositories will belong
+to them in the filesystem.
+
+{%
+ include-markdown "../includes/ondemand/installing.md"
+ heading-offset=1
+%}
+
+{%
+ include-markdown "../includes/hguser.md"
+ heading-offset=1
+%}
+
+{%
+ include-markdown "../includes/ondemand/adminrepository.md"
+ heading-offset=1
+%}
+
+{%
+ include-markdown "../includes/ondemand/openssh.md"
+ heading-offset=1
+%}
+
+## Testing
+
+You should now be able to clone the `hgkeeper` administration repo through
+your normal OpenSSH Server. You can verify this by trying to clone the
+`hgkeeper` administration repository with the following command replacing
+`<my hostname>` with the actual hostname of your server.
+
+```
+hg clone ssh://<my hostname>/hgkeeper
+```
+
+If the repository cloned, you are good to go!
+
+If that didn't work, be sure to double check all of your configuration.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/reverseproxy.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,60 @@
+# Reverse Proxying
+
+It is possible to use OpenSSH to reverse proxy to HGKeeper's SSH server. There
+are a number of reasons you may want to do this. You don't want to expose
+HGKeeper to your network or the internet, you want to use your existing
+OpenSSH server so you don't need to specify a different port, or maybe you have
+another reason we can't think of right now.
+
+Once you have setup either a [standalone](../standalone) or
+[standalone container](../standalonecontainer) instance you can proxy it
+through an OpenSSH server in a few steps.
+
+## Prerequisites
+
+For this to work, you will need to specify the `--external-hostname` arguement
+via the command line or its environment varible counter part. If you're running
+on a port other than `22222` you'll need to do the same with `--external-port`.
+
+You will also need `curl` installed on the machine running the OpenSSH Server.
+
+{%
+ include-markdown "../includes/hguser.md"
+ heading-offset=1
+%}
+
+## SSH Known Hosts
+
+Before we update the OpenSSH Server to do the remote proxy, we need to store
+the HGKeeper's public host keys in our `hg` users `known_hosts` file. The
+easiest way to do this is to open a shell as the `hg` user and use
+`ssh-keyscan` to acquire the keys.
+
+You can use the following commands to accomplish this. Make sure to swap in the
+proper values for `<external-hostname>` and `<external-port>` for your
+environment.
+
+```sh
+sudo su hg
+ssh-keyscan -H <external-hostname> -p <external-port> | tee -a ~/.ssh/known_hosts
+```
+{%
+ include-markdown "../includes/reverseproxy/openssh.md"
+ heading-offset=1
+%}
+
+## Testing
+
+You should now be able to clone the `hgkeeper` administration repository
+through your existing OpenSSH Server. You can use the following command to
+verify that everything has been setup correctly.
+
+```
+hg clone ssh://hg@example.com/hgkeeper
+```
+
+If the repository cloned, you are good to go!
+
+If that didn't work, be sure to check the logs from your OpenSSH Server as well
+as your HGKeeper instance, and be sure to double check your configuration.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/runmodes.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,10 @@
+# Running
+
+There are multiple ways to run HGKeeper. It can be run in a
+[container](container), as a [standalone](standalone) service directly on a
+host, or executed [on demand](ondemand) by [OpenSSH](https://www.openssh.com/).
+
+Both running in a [container](container) and running and
+[standalone](standalone) can also be integrated with
+[OpenSSH](https://www.openssh.com/) as well.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/sshaccess.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,84 @@
+# SSH Access
+
+How you access HGKeeper over SSH will depend a lot on the
+[run mode](../runmodes) as well as how the server has been configured. However,
+there are some not so obvious things to HGKeeper that need to be addressed.
+
+## Remote URLs
+
+Cloning, pushing, and pulling are going to be just like they are for any SSH
+based Mercurial hosting. Of course you will have to match the port number in
+your remote url to match.
+
+If you're running HGKeeper in [standalone mode](../standalone) with it's
+default port of `22222` you'll need to specify that port when cloning:
+
+```sh
+hg clone ssh://example.com:22222/hgkeeper
+```
+
+If you're running HGKeeper behind OpenSSH in either [on demand](../ondemand) or
+[reverse proxy](../reverseproxy) mode, then you must specify the user name you
+have configured:
+
+```sh
+hg clone ssh://hg@example.com/hgkeeper
+```
+
+## Creating Repositories
+
+HGKeeper's web interface is just
+[hgweb](https://www.mercurial-scm.org/wiki/PublishingRepositories#hgweb), which
+means there is no way to create repositories from the web interface.
+
+However, `hg init`, which we use to create repositores locally, also works on a
+remote. So to create a repository, assuming you have the `init` permission in
+the authorization policy, you can use the following command:
+
+```
+hg init ssh://hg@example.com/coolstuff/frontend
+```
+
+If this completes without displaying an error, you can now clone the brand new
+empty repository with the following command:
+
+```
+hg clone ssh://hg@example.com/coolstuff/frontend
+```
+
+## Gotchas
+
+As you may have imagined, integrating with OpenSSH can be somewhat difficult to
+get correct and even then there are some issues that crop up that may leave you
+stumped. This section aims to alleviate these issues.
+
+### Reverse Proxying
+
+HGKeeper works like any other Mercurial service that is hosted over SSH.
+However, if you are running HGKeeper in [reverse proxy](../reverseproxy) mode
+with OpenSSH infront of it, you will need to use an SSH Agent and make sure
+that it is being forwarded when connecting to your server.
+
+On Linux/BSD, you can easily do this by adding a host configuration to your
+`~/.ssh/config` file. Be sure to replace `hg` and `example.com` with your
+real values.
+
+```ssh_config
+match User hg Host example.com
+ ForwardAgent yes
+```
+
+### No Mutual Signature Algorithm
+
+Recent releases of OpenSSH Server have
+[disabled rsa signatures](https://www.openssh.com/txt/release-8.7). If you are
+using an `RSA` based host key, you will need to add a section to your
+`~/.ssh/config` to permit this. But please note, this is currently deprecated
+and is planned to be removed in the future, so this setting is just to keep you
+running while you work on migrating to a more secure host key.
+
+```ssh_config
+match User hg Host example.com
+ PubkeyAcceptedKeyTypes ssh-rsa
+```
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/docs/standalonecontainer.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,51 @@
+# Standalone Container
+
+When running a standalone container users will be connecting directly to
+HGKeeper for both HTTP and SSH access. You can put an HTTP reverse proxy in
+front of HGKeeper's HTTP server if you would like to add TLS support as
+HGKeeper does not currently offer direct TLS support.
+
+This methods is how we run our own instance under
+[Kubernetes](https://kubernetes.io/). If you're interested in learning more
+about our setup, you can find our
+[Kustomization](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/)
+manifests at
+[keep.imfreedom.org/imfreedom/k8s-cluster/](https://keep.imfreedom.org/imfreedom/k8s-cluster/file/default/50-keep.imfreedom.org).
+
+{%
+ include-markdown "../includes/container.md"
+ heading-offset=1
+%}
+
+{%
+ include-markdown "../includes/adminrepositorycontainer.md"
+ heading-offset=1
+%}
+
+{%
+ include-markdown "../includes/hostkeys.md"
+ heading-offset=1
+%}
+
+{%
+ include-markdown "../includes/runningcontainer.md"
+ heading-offset=1
+%}
+
+## Testing
+
+You should now be able to clone the `hgkeeper` administration repo from the
+container. We will use the following command to verify that everything has been
+setup correctly.
+
+From your host, run the following command:
+
+```
+hg clone ssh://localhost:22222/hgkeeper
+```
+
+If the repository cloned, you are good to go!
+
+If that didn't work, be sure to check the logs of the HGKeeper container and
+double check all of your configuration.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/adminrepositorycontainer.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,32 @@
+# Administration Repository
+
+First we will create the HGKeeper administration repository. We will use the
+normal HGKeeper container with an overridden command to run the setup. An extra
+step with this method is that you will need to volume mount a file containing
+the public key of the initial administrator into this invocation. In the
+following example we assume that the key is in `~/.ssh/id_ed25519.pub`.
+
+Be sure to replace the value of `my_username` with the username that would like
+to use.
+
+Also, since this container is just used for initialization of the
+administration repository, we will pass the `--rm` flag to make sure it will be
+deleted when done.
+
+```
+docker run --rm \
+ --volume $(pwd)/repos:/repos \
+ --volume ~/.ssh/id_ed25519.puc:/admin-pubkey:ro \
+ --env HGK_ADMIN_USERNAME=my_username \
+ --env HGK_ADMIN_PUBKEY=/admin-pubkey \
+ --env HGK_REPOS_PATH=/repos \
+ docker.io/rwgrim/hgkeeper:latest \
+ hgkeeper setup
+```
+
+Once this step has completed, you should now have a `repos` directory in your
+current working directory and it should have a brand new `hgkeeper`
+administration repository in it. These repositories are HGKeeper's copies of
+them, you should not modify them directly and should be using the SSH
+capabilities of HGKeeper to push/pull to/from them.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/container.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,13 @@
+# Container
+
+HGKeeper is available at
+[docker.io/rwgrim/hgkeeper](https://hub.docker.com/r/rwgrim/hgkeeper) which is
+updated via CI. Currently only a `latest` tag is provided.
+
+HGKeeper should work under any container runtime, but has been tested with
+Docker, containerd/runc, and podman. The documentation below uses the Docker
+command line as it appears to be the most popular at the moment.
+
+Like all modes of operation, running in a container is going to require an
+`hgkeeper` administration repository and at least one SSH host key.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/hguser.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,16 @@
+# Create The `hg` User
+
+You can name this user whatever you like, but for the sake of simplicity, we
+just be using `hg` here. We are also going to createan `hg` group to keep to
+make sure file permissions remain tight. For most Linux/BSD distributions, you
+can create the `hg` user and group with the following commands:
+
+```
+sudo groupadd --system hg
+sudo useradd --home-dir /var/lib/hg --create-home --system --gid hg
+```
+
+This is the username that you will need to specify when connecting to the
+OpenSSH Server and is how we will configure the server to tell it how to serve
+Mercurial repositories.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/hostkeys.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,27 @@
+# SSH Host Keys
+
+Since HGKeeper provies and SSH server, you will need to generate SSH host keys
+for it. You can disable the SSH server if you like, see the [usage](usage)
+documentation for more information.
+
+You can generate SSH host keys for whatever key type you prefer, but we would
+recommend not using `ssh-rsa` as it's been deprecated and schedule for removal
+in [OpenSSH 8.7](https://www.openssh.com/txt/release-8.7). So for the purpose
+of this documentation, we will be using `ed25519` keys.
+
+By default, the SSH host keys will be looked for in the directory `host-keys`
+in the working directory of HGKeeper. This can be changed via the
+`ssh-host-keys-path` command line argument or the `HGK_SSH_HOST_KEYS_PATH`
+environment variable.
+
+This directory will be read and any files in it will attempt to be loaded as
+SSH host keys into the server.
+
+To generate a host key you can use the following command. Note that you can
+create other types via the `-t` command line argument, but you should read the
+`ssh-keygen` documentation as other options are available for each type.
+
+```
+$ ssh-keygen -t ed25519 -o host-keys/ssh_host_ed25519_key
+```
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/ondemand/adminrepository.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,27 @@
+# Administration Repository
+
+To make life easier, we're going to run the setup command as the `hg` user. The
+easiest way to do this is with the following commands:
+
+```
+sudo su hg
+cd ~
+whoami
+```
+
+We changed to the `hg` users home directory as this is where we are going to
+store all of the files. The last line of output should just say `hg` which we
+are using to verify that you did in fact switch to the `hg` user.
+
+Now that we're in the proper location we can create the administration
+repository. For this, we'll need an SSH public key of the initial administrator
+saved in a file, and a name for the administrator. The name is used to
+determine where to put the public key and by the authentication system.
+
+In this example, we have the administrator's SSH public key in a file named
+`admin.pub` in the current directory. We are also giving them a name of `me`.
+
+```
+hgkeeper setup --admin-pubkey=admin.pub --admin-username=me
+```
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/ondemand/installing.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,25 @@
+# Installing
+
+When running in on demand mode HGKeeper needs to be installed in a place where
+OpenSSH Server can find it. However, since OpenSSH Server is also going to be
+running it, there are some additional requirements that must be met.
+
+These requirements are that the program:
+
+ * must be owned by root
+ * is not writeable by group or others
+ * is specified by an absolute path
+
+Luckily for us, something like `/usr/local/bin` meets all of these requirements
+and will put it on the `$PATH` so that we can use it to set up the
+administration repository later.
+
+So we will just copy the file to `/usr/local/bin/` and make sure it has a file
+mode of `0755`:
+
+```
+sudo cp hgkeeper /usr/local/bin/
+sudo chown root:root /usr/local/bin/hgkeeper
+sudo chmod 0755 /usr/local/bin/hgkeeper
+```
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/ondemand/openssh.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,21 @@
+# Configuring OpenSSH Server
+
+Configuring OpenSSH Server is very straight forward. All we need to do is drop
+the following snippet into `/etc/ssh/sshd_config`. Of course, if you customized
+the install location or username you will have to adjust the snippet.
+
+You may be able to use `/etc/ssh/sshd_config.d/hgkeeper.conf` but in our
+testing on Debian unstable we were unable to get it working properly. If you
+have some pointers here, we'd love to hear them!
+
+```
+Match User hg
+ AuthorizedKeysCommand /usr/local/bin/hgkeeper --repos-path=/var/lib/hg/repos/ authorized-keys %f
+ AuthorizedKeysCommandUser hg
+ PasswordAuthentication no
+```
+
+Open you've saved the file, you will need to reload OpenSSH Server. This is
+usually done via `sudo service ssh reload` but will vary based on your
+operating system.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/reverseproxy/openssh.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,23 @@
+# Configuring OpenSSH Server
+
+Configuring OpenSSH Server is very straight forward. All we need to do is drop
+the following snippet into `/etc/ssh/sshd_config`. Of course, if you customized
+the `hg` username you will have to adjust the snippet.
+
+You may be able to use `/etc/ssh/sshd_config.d/hgkeeper.conf` but in our
+testing on Debian unstable we were unable to get it working properly. If you
+have some pointers here, we'd love to hear them!
+
+In the following snippet, be sure to replace `<external-hostname>`, `<external-post>`, and the `hg` user with the proper values for your environment.
+
+```
+Match User hg
+ AuthorizedKeysCommand /usr/bin/curl -q --get --data-encode "fp=%f" http://<external-hostname>:<external-http-port>/hgk/authorized_keys
+ AuthorizedKeysCommandUser hg
+ PasswordAuthentication no
+```
+
+Open you've saved the file, you will need to reload OpenSSH Server. This is
+usually done via `sudo service ssh reload` but will vary based on your
+operating system.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/runningcontainer.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,26 @@
+# Running The Container
+
+Now that we have the adminstration repository as well as the SSH host keys, we
+can finally run HGKeeper.
+
+The following example command makes the same assumptions as the `setup`
+container did above. However, it's going to expose the container on the host's
+network interface. We also run it in the background and give it a name of
+`HGKeeper`. If you're just doing testing, you will probably want to remove the
+`--detach`, `--name hgkeeper`, and `--restart=unless-stopped` options.
+
+```
+docker run \
+ --detach \
+ --name hgkeeper \
+ --restart=unless-stopped \
+ --volume $(pwd)/host-keys:/host-keys:ro \
+ --volume $(pwd)/repos:/repos \
+ --env HGK_SSH_HOST_KEYS=/host-keys \
+ --env HGK_REPOS_PATH=/repos \
+ --publish 8080:8080 \
+ --publish 22222:22222 \
+ docker.io/rwgrim/hgkeeper:latest \
+ hgkeeper serve
+```
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/includes/sshclientconfig.md Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,3 @@
+# SSH Client Configuration
+
+Since we
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/mkdocs.yml Wed Mar 23 13:28:31 2022 -0500
@@ -0,0 +1,21 @@
+site_name: HGKeeper
+site_url: https://docs.imfreedom.org/hgkeeper/
+copyright: Copyright &copy; 2019-2022 <a href="https://reaperworld.com/">Gary Kramlich</a>
+repo_url: https://keep.imfreedom.org/grim/hgkeeper
+repo_name: Source Code
+nav:
+ - About: index.md
+ - User Guide:
+ - SSH Access: sshaccess.md
+ - Access Control: accesscontrol.md
+ - Command Reference: commandreference.md
+ - Running:
+ - 'Run Modes': runmodes.md
+ - 'On Demand': ondemand.md
+ - 'Standalone Container': standalonecontainer.md
+ - 'Reverse Proxy': reverseproxy.md
+ - Issues: 'https://issues.imfreedom.org/issues/HGKEEPER?u=1'
+plugins:
+ - include-markdown
+ - search
+