vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Add automatic HTTPS with ACME
642e599466fe4f5066afdc9a24775694a52c9749 · Keenan Nemetz · 15d ago · parent 91e6a33a
forge/config/config.go +40−4
| @@ -13,8 +13,22 @@ import ( | |||
| 13 | 13 | ||
| 14 | 14 | type Config struct { | |
| 15 | 15 | DataDir string `toml:"data_dir"` | |
| 16 | // HTTPAddr serves the web UI and anonymous git clone. | ||
| 16 | // HTTPAddr serves the web UI and anonymous git clone. When HTTPSAddr is | ||
| 17 | // set it instead answers ACME HTTP-01 challenges and redirects to HTTPS. | ||
| 17 | 18 | HTTPAddr string `toml:"http_addr"` | |
| 19 | // HTTPSAddr enables automatic HTTPS with ACME. Empty leaves TLS to a proxy. | ||
| 20 | HTTPSAddr string `toml:"https_addr"` | ||
| 21 | // ACMEEmail is the contact address given to the certificate authority. | ||
| 22 | ACMEEmail string `toml:"acme_email"` | ||
| 23 | // ACMEDomains are the host names Vole may obtain certificates for. When | ||
| 24 | // empty, the host in PublicURL is used. Each host gets its own certificate. | ||
| 25 | ACMEDomains []string `toml:"acme_domains"` | ||
| 26 | // ACMECacheDir stores the ACME account key and issued certificates. Empty | ||
| 27 | // means <data_dir>/acme. | ||
| 28 | ACMECacheDir string `toml:"acme_cache_dir"` | ||
| 29 | // ACMEDirectoryURL overrides the certificate authority, for a private ACME | ||
| 30 | // server or the Let's Encrypt staging directory while testing. | ||
| 31 | ACMEDirectoryURL string `toml:"acme_directory_url"` | ||
| 18 | 32 | // SSHAddr is the only write githttp. | |
| 19 | 33 | SSHAddr string `toml:"ssh_addr"` | |
| 20 | 34 | // MaxBlobBytes rejects individual objects in pre-receive. | |
| @@ -171,6 +185,16 @@ func (c *Config) Lease() time.Duration { | |||
| 171 | 185 | } | |
| 172 | 186 | func (c *Config) SSHHostKey() string { return filepath.Join(c.DataDir, "ssh_host_ed25519_key") } | |
| 173 | 187 | ||
| 188 | // ACMECachePath is where automatic-HTTPS state lives. The ACME account key is a | ||
| 189 | // secret, so it belongs beside the SSH host key rather than in a world-readable | ||
| 190 | // system directory. | ||
| 191 | func (c *Config) ACMECachePath() string { | ||
| 192 | if dir := strings.TrimSpace(c.ACMECacheDir); dir != "" { | ||
| 193 | return dir | ||
| 194 | } | ||
| 195 | return filepath.Join(c.DataDir, "acme") | ||
| 196 | } | ||
| 197 | |||
| 174 | 198 | // BaseURL is PublicURL without a trailing slash, so a caller can append | |
| 175 | 199 | // "/r/<repo>/issues/<id>" without thinking about it. | |
| 176 | 200 | func (c *Config) BaseURL() string { return strings.TrimRight(c.PublicURL, "/") } | |
| @@ -180,11 +204,23 @@ func Sample() string { | |||
| 180 | 204 | return `# Vole configuration | |
| 181 | 205 | data_dir = "./data" | |
| 182 | 206 | ||
| 183 | # Read-only: the web UI and anonymous git clone. | ||
| 184 | # TLS is not Vole's job: terminate it in a proxy in front of this address and keep | ||
| 185 | # the Host header intact, because site requests are routed by hostname. | ||
| 207 | # Read-only: the web UI and anonymous git clone. Leave HTTPS off and terminate | ||
| 208 | # TLS in a proxy in front of this address, keeping the Host header intact because | ||
| 209 | # site requests are routed by hostname. | ||
| 186 | 210 | http_addr = "127.0.0.1:8080" | |
| 187 | 211 | ||
| 212 | # Or let Vole obtain and renew its own certificates with ACME. Setting https_addr | ||
| 213 | # enables it; http_addr then answers ACME challenges and redirects to HTTPS, so | ||
| 214 | # it must be reachable on port 80. public_url below (or acme_domains) must name | ||
| 215 | # a host that resolves to this server. | ||
| 216 | # https_addr = ":443" | ||
| 217 | # http_addr = ":80" | ||
| 218 | # acme_email = "admin@example.com" | ||
| 219 | # acme_domains = ["forge.example.com"] | ||
| 220 | # acme_cache_dir = "./data/acme" | ||
| 221 | # Use the staging directory while testing to avoid a production rate limit. | ||
| 222 | # acme_directory_url = "https://acme-staging-v02.api.letsencrypt.org/directory" | ||
| 223 | |||
| 188 | 224 | # The only write githttp. Identity is the SSH key presented at handshake. | |
| 189 | 225 | ssh_addr = "127.0.0.1:2222" | |
| 190 | 226 | ||