flounder

A simple gemini site builder
Log | Files | Refs | README | LICENSE

commit 8474a31970a838cf6016b418b857e8a7e313cd87
parent d083fbf8a06a861d62e355ad64192bd2c313565d
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sun, 31 Jan 2021 11:59:03 -0800

Simplify self-hosting guidelines

Diffstat:
MREADME.md | 36++++++++++++++++++------------------
Mconfig.go | 2--
Mexample-config.toml | 11++++-------
Mgmi2html.go | 4----
Mhttp.go | 14++++++++------
Mtemplates/header.html | 2+-
Mutils.go | 3+++
7 files changed, 34 insertions(+), 38 deletions(-)

diff --git a/README.md b/README.md @@ -7,39 +7,39 @@ Flounder is in ALPHA -- development and features are changing frequently, especi See the flagship instance at https://flounder.online and gemini://flounder.online ## Building +Requirements: +go >= 1.15 +sqlite dev libraries -Requires go >= 1.15 and sqlite3 development libraries. +To run locally, copy example-config.toml to flounder.toml, then run: -`go build` +`go run . serve` -To run locally, you can use the example-config.toml to start a test server. +Add the following to `/etc/hosts` (include any other users you want to create): -`./flounder -c example-config.toml serve` +``` +127.0.0.1 flounder.local admin.flounder.local proxy.flounder.local +``` -After creating an account, you can activate it at the command line with: - -./flounder -c example-config.toml activate-user [your-username] - -## Deploying +## TLS Certs and Reverse Proxy Gemini TLS certs are handled for you. For HTTP, you'll need a reverse proxy that does the following for you: -1. Wildcard for \*.yourdomain.whatever +1. Cert for yourdomain.whatever +1. Wildcard cert for \*.yourdomain.whatever 2. On Demand cert for custom user domains -If you have a very small deployment <20 users, for example, you can use on demand cert for all domains, and don't have to setup a wildcard cert, for simplicity. - -I'm using Caddy. I haven't tested any other servers. +If you have a very small deployment of say, <100 users, for example, you can use on demand cert for all domains, and you can skip step 2. -I have not extensively tested the self-hosting capabilities, but making it easy to self-host Flounder for either a single or multi-user instance is a goal of mine. There may be minor issues where "flounder.online" is hardcoded, but I'm trying to fix them. Email me if you encounter issues or would like guidance. +However, for a larger deployment, you'll have to set up a wildcard cert. Wildcard certs are a bit of a pain and difficult to do automatically, depending on your DNS provider. For information on doing this via Caddy, you can follow this guide: https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148. -## Admin +For information on using certbot to manage wildcard certs, see this guide: https://letsencrypt.org/docs/challenge-types/#dns-01-challenge -To make yourself an admin, create a user through the web browser, then run `./flounder -c [config_path] make-admin [your user]` -- this gives you access to admin tools to manage users. +An example simple Caddyfile using on-demand certs is available in Caddyfile.example -Backup your users' data regularly! The admin deletion commands are irreversible. +If you want to host using a server other than Caddy, there's no reason you can't, but it may be more cumbersome to setup the http certs. -Flounder comes with an admin panel accessible to users with the admin db flag set. Admins can also impersonate users if you need to take actions like moderating their content, deleting their account, changing their password, etc. +You can run this locally by removing the port from the Host config ## Development diff --git a/config.go b/config.go @@ -24,8 +24,6 @@ type Config struct { OkExtensions []string MaxFileBytes int MaxUserBytes int64 - TLSCertFile string - TLSKeyFile string SMTPServer string SMTPUsername string SMTPPassword string diff --git a/example-config.toml b/example-config.toml @@ -2,9 +2,11 @@ SiteTitle="demoflounder" # Include port if running locally -Host="localhost:8165" +Host="flounder.local:8165" +# Running through reverse proxy +# Host="flounder.local" -# Set this depending on whether you want to run this service standalone or through a reverse proxy server +# Port to run on HttpPort=8165 # Folder containing subfolders for each user's files @@ -14,11 +16,6 @@ LogFile="./flounder.log" # Gemini autogenerates self-signed certs GeminiCertStore="/tmp" -# A wildcard TLS cert for HTTPS. -# Only required if HttpsEnabled=true -# TLSCertFile="./server.crt" -# TLSKeyFile="./server.key" - # Optional SMTP -- to send notification emails to users on acct activation # SMTPServer = mail.goodsite.com:587 # SMTPUsername = myemail@coolplace.com diff --git a/gmi2html.go b/gmi2html.go @@ -99,7 +99,3 @@ func textToHTML(reqUrl *url.URL, text gemini.Text) string { } return b.String() } - -// Convert a Gemini link to a proxy link -func proxyLink() { -} diff --git a/http.go b/http.go @@ -725,8 +725,12 @@ func checkDomainHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte(domain)) return } + if domain == c.Host || strings.HasSuffix(domain, "."+c.Host) { + w.Write([]byte(domain)) + } http.Error(w, "Not Found", 404) } + func runHTTPServer() { log.Printf("Running http server with hostname %s on port %d.", c.Host, c.HttpPort) var err error @@ -745,7 +749,6 @@ func runHTTPServer() { s := strings.SplitN(c.Host, ":", 2) hostname := s[0] - port := c.HttpPort serveMux.HandleFunc(hostname+"/", rootHandler) serveMux.HandleFunc(hostname+"/my_site", mySiteHandler) @@ -769,18 +772,17 @@ func runHTTPServer() { wrapped := handlers.CustomLoggingHandler(log.Writer(), handlers.RecoveryHandler()(serveMux), logFormatter) - // handle user files based on subdomain + // handle user files based on subdomain or custom domains // also routes to proxy - serveMux.HandleFunc("proxy."+hostname+"/", proxyGemini) // eg. proxy.flounder.online + serveMux.HandleFunc("proxy."+hostname+"/", proxyGemini) serveMux.HandleFunc("/", userFile) // login+register functions srv := &http.Server{ ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, IdleTimeout: 120 * time.Second, - Addr: fmt.Sprintf(":%d", port), - // TLSConfig: tlsConfig, - Handler: wrapped, + Addr: fmt.Sprintf(":%d", c.HttpPort), + Handler: wrapped, } log.Fatal(srv.ListenAndServe()) } diff --git a/templates/header.html b/templates/header.html @@ -5,7 +5,7 @@ <meta charset="utf-8" /> <title>{{.Config.SiteTitle}}</title> <meta name="viewport" content="width=device-width" /> - <link rel="stylesheet" type="text/css" href="https://{{.Config.Host}}/style.css" /> + <link rel="stylesheet" type="text/css" href="//{{.Config.Host}}/style.css" /> <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🐟</text></svg>"> </head> <body> diff --git a/utils.go b/utils.go @@ -14,6 +14,9 @@ import ( "unicode/utf8" ) +func buildbaseURL(user string) { +} + func getSchemedFlounderLinkLines(r io.Reader) []string { scanner := bufio.NewScanner(r) result := []string{}