Skip to content

Instantly share code, notes, and snippets.

@therealchjones
Last active May 25, 2024 23:04
Show Gist options
  • Save therealchjones/4be138411e97eeda6571a035754b744e to your computer and use it in GitHub Desktop.
Save therealchjones/4be138411e97eeda6571a035754b744e to your computer and use it in GitHub Desktop.
seedhost web serving

Seedhost's web server structure

I don't know if this applies to all Seedhost servers, just "Dedicated Hosting", or just the server I use. I've made some notes here because it's not entirely straightforward and doesn't appear to be documented elsewhere. If you're looking to host your own content on a Seedhost box, however, it may be useful to know how the system is arranged and what you can do with it.

Primary external web server: nginx

  • nginx listens on 80 and 443 (ssl) with default server_name set to servername.seedhost.eu (mine is server1359.seedhost.eu).
  • Configuration is loaded from these files, which are not user-modifiable
    • /etc/nginx/nginx.conf
    • /etc/nginx/conf.d/default.conf
    • /etc/nginx/conf.d/hosts/*.conf
    • /etc/nginx/hosts/*.conf
  • / serves index.html or index.htm from /usr/share/nginx/html
    • some custom error pages (50x and 404) are set up to be in the same directory, but don't actually exist
  • /username/ acts as a proxy to http://username.servername.seedhost.eu
  • apps you have installed may use rewrite rules and proxies included in /etc/nginx/conf.d/hosts/ to provide access to their web interfaces. At least the following apps create proxies at /username/appname/, typically to 127.0.0.1:app port.
    • deluge
    • transmission
    • overseerr
    • prowlarr
    • radarr
  • if the requested host is username.servername.seedhost.eu or *.username.servername.seedhost.eu, then the Host header is set to the former and / serves as a proxy to 127.0.0.1:8000
    • while this works on ports 80 and 443 (for ssl), the SSL certificate served is for *.seedhost.eu and is thus not a match for username.servername.seedhost.eu; it will be considered invalid by most rules (note that this is not an issue if visiting https://servername.seedhost.eu/username/, since it proxies username.servername.seedhost.eu via http.)
  • the user does not have read access to the error and access logs
  • the seedhost configuration does not appear to load any of the other config files, such as those in /etc/nginx/sites-enabled

User-modifiable web server: Apache

  • apache listens on port 8000 with default server name username.servername.seedhost.eu
  • configuration is loaded from
    • /etc/apache2/apache2.conf
    • /etc/apache2/envvars
    • /etc/apache2/mods-enabled/*.load
    • /etc/apache2/mods-enabled/*.conf
    • /etc/apache2/conf.d/
    • ~username/.apache2/conf.d/
  • the document root is set to ~username/www/hostname/; most of the time this will be ~username/www/username.servername.seedhost.eu/ (including if accessed via IP rather than hostname), but if accessed by a different hostname (e.g., localhost), the document root changes
  • document root has AllowOverride All and Options +Indexes set
  • DirectoryIndex is set to index.html index.cgi index.pl index.php index.xhtml index.htm
  • The following modules are enabled (and possibly configured) in /etc/apache2/mods-enabled:
    • mod_access_compat
    • mod_alias
    • mod_auth_basic
    • mod_authn_core
    • mod_authn_file
    • mod_authz_core
    • mod_authz_host
    • mod_authz_user
    • mod_autoindex
    • mod_deflate
    • mod_dir
    • mod_env
    • mod_filter
    • mod_mime
    • mod_mpm_prefork
    • mod_negotiation
    • libphp7.4
    • mod_reqtimeout
    • mod_rewrite
    • mod_scgi
    • mod_setenvif
    • mod_socache_shmcb
    • mod_ssl
    • mod_status
    • mod_vhost_alias
  • The following modules are loaded (and may be configured) in ~/.apache2/conf.d
    • mod_proxy
    • mod_proxy_http
    • mod_headers
    • mod_ssl
  • /username/RPC1 is an SCGI mount point to 127.0.0.1:5000 (which may be used by rtorrent) using basic auth for your user
  • /username/rutorrent1/RPC1 is an SCGI mount point to 127.0.0.1:13353 (which may be used by rutorrent) using basic auth for user rutorrent1
  • dynamic server status is available at http://localhost:8000/server-status via mod_status
  • proxies to some installed apps (typically 127.0.0.1:appport) are at /chjones/appname/, at least for
    • bazarr
    • sonarr
  • There are user-accessible logs and configuration files in ~/.apache2/; note that you do not have to limit your configuration to .htaccess files
  • the seedhost configuration does not appear to load any of the other config files, such as those in /etc/apache2/sites-enabled and /etc/apache2/ports.conf

Putting it together: changing configuration and adding content

  • Ihe nginx server is hardly configurable for the end user, and http(s)://servername.seedhost.eu will just continue to point to the nginx "Welcome to nginx!" placeholder page.
  • It may be possible to use https://host/username/appname as an address for user content (especially if you don't have an app named appname installed), but is more likely to break something. Avoid.
  • Note that requests for the apps noted above as proxied by nginx don't pass through the Apache server at all; if you wish to customize anything about accessing them you'll have to change their settings and re-proxy them through Apache instead. I haven't tested this.
  • https://servername.seedhost.eu/username/path is an easy (and SSL-valid) way to access ~/www/username.servername.seedhost.eu/username/path; note the username before the rest of the path is necessary in both cases
  • To bypass the nginx server completely requires using http (not https) over port 8000, and this will serve content from the specified host directory. For instance:
    • http://username.servername.seedhost.eu:8000/path serves ~/www/username.servername.seedhost.eu/path (note this does not require the username before the path as above)
    • http://localhost:8000/*path* serves ~/www/localhost/path
    • http://127.0.0.1:8000/*path* serves ~/www/username.servername.seedhost.eu/path (as does any other http://ipaddress:8000/path without a host name in the request header)
    • http://servername.seedhost.eu:8000/path serves ~/www/servername.seedhost.eu/path, not the same as http://username.servername.seedhost.eu:8000 or http(s)://servername.seedhost.eu/username/
  • Using https://username.servername.seedhost.eu/path or https://subdomain.username.servername.seedhost.eu/path will serve ~/www/username.servername.seedhost.eu/path (without the username prefixing the path), but will result in an SSL certificate validation error

Example - using a custom domain to serve user content from Seedhost

For the best visitor experience, we must avoid the aforementioned SSL certificate error as well as unnecessary path or hostname components. For the best developer experience, we should have as much control as possible over what kind of content can be served. To meet these goals requires:

  • DNS settings access for domain
  • A proxy service with either the ability to ignore SSL errors or rewrite the request path

My current setup:

  • domain registration along with free DNS hosting and proxy service from Cloudflare
  • subdomain (not my root domain) has CNAME set to servername.seedhost.eu with Cloudflare proxy on. (This would likely work with subdomain or even the root domain having an A record that's pointing to the IP address for servername.seedhost.eu, but I haven't tested that.)
  • Cloudflare redirects all http traffic to https
  • Cloudflare SSL/TLS encryption mode is Full (strict)
  • A Cloudflare Transform rule rewrites requests to subdomain that have paths which don't start with /username/ and which don't equal /username so that the new path (not displayed to visitors) prepends /username/
  • Thus a request http(s)://subdomain/path is sent to Cloudflare, which in turn requests https://servername.seedhost.eu/username/path (if the original path did not start with /username/), which the nginx proxy requests as http://username.servername.seedhost.eu/username/path, which the nginx proxy requests as http://127.0.0.1:8000/*username*/*path* (with the hostname header set to username.servername.seedhost.eu), which Apache serves from ~username/www/username.servername.seedhost.eu/username/path.
  • Anything desired about the Apache server can be changed with configuration files in ~username/.apache2/conf.d/, including breaking the server so that none of the existing apps work anymore and/or none of the above holds true. Use caution.
  • Note that if path starts with username, it is not again prepended.
  • Additionally, if path starts with an installed appname/, RPC1/, it may have undesirable effects (unless you're simply trying to make it easier to manage an app with a direct URL, which is what this presents). Don't put your own content at one of these paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment