A smart redirecting gateway for various frontend services
Go to file
Ben Busby a6dabe8bf3
Make conn values and services path configurable at runtime
Connection values (such as redis server port and the port to run farside
on) as well as the services json file to use can now be set via
environment variables:

FARSIDE_PORT sets the port for Farside to run on
FARSIDE_REDIS_PORT sets the redis server port for Farside to use
FARSIDE_SERVICES_JSON sets the services json file for Farside to use

This partially addresses the move towards de-listing Cloudflare
instances by default by allowing different services json files to be
used with different redis servers.

See #43
2022-07-27 13:53:33 -06:00
.github/workflows Exclude i2p address from searx(ng) auto update 2022-07-13 10:53:27 -06:00
config Make conn values and services path configurable at runtime 2022-07-27 13:53:33 -06:00
img Convert logo to SVG 2021-11-12 17:04:34 -07:00
lib Make conn values and services path configurable at runtime 2022-07-27 13:53:33 -06:00
test Make conn values and services path configurable at runtime 2022-07-27 13:53:33 -06:00
.formatter.exs Setup basic Plug.Router framework for serving requests 2021-10-22 18:28:12 -06:00
.gitignore Auto select frontend for links to "parent" service 2022-06-09 13:08:01 -06:00
index.eex Add margin to service list ul element 2021-11-23 14:36:54 -07:00
LICENSE Initial commit 2021-10-21 15:50:04 -06:00
mix.exs Replace poison dependency w/ jason 2022-02-14 11:21:32 -07:00
mix.lock Use quantum core for update scheduling 2021-11-24 09:35:21 -07:00
README.md Make conn values and services path configurable at runtime 2022-07-27 13:53:33 -06:00
route.eex Include query params for all /_/ prefixed links 2022-06-13 10:20:39 -06:00
services.json [CI] Auto update instances 2022-07-27 00:12:25 +00:00

Farside

Latest Release MIT License Elixir CI

A redirecting service for FOSS alternative frontends.

Farside provides links that automatically redirect to working instances of privacy-oriented alternative frontends, such as Nitter, Libreddit, etc. This allows for users to have more reliable access to the available public instances for a particular service, while also helping to distribute traffic more evenly across all instances and avoid performance bottlenecks and rate-limiting.

Demo

Farside's links work with the following structure: farside.link/<service>/<path>

For example:

Service Page Farside Link
Libreddit /r/popular https://farside.link/libreddit/r/popular
Teddit /r/popular https://farside.link/teddit/r/popular
Nitter User Profile https://farside.link/nitter/josevalim
Invidious Home Page https://farside.link/invidious
Piped Video Page https://farside.link/piped/watch?v=eBGIQ7ZuuiU
Bibliogram User Profile https://farside.link/bibliogram/u/kbdfans
Whoogle Search "Elixir" https://farside.link/whoogle/search?q=elixir&lang_interface=en
SearX Search "Redis" https://farside.link/searx/search?q=redis
SearXNG Search "EFF" https://farside.link/searxng/search?q=EFF
SimplyTranslate Translate "hola" https://farside.link/simplytranslate/?engine=google&text=hola
Lingva Translate "bonjour" https://farside.link/lingva/auto/en/bonjour
Rimgo View photo album https://farside.link/rimgo/a/H8M4rcp
Scribe View Medium post https://farside.link/scribe/@ftrain/big-data-small-effort-b62607a43a8c

This table doesn't include all available services. For a complete list of supported frontends, see: https://farside.link

Farside also accepts URLs to "parent" services, and will redirect to an appropriate front end service, for example:

How It Works

The app runs with an internally scheduled cron task that queries all instances for services defined in services.json every 5 minutes. For each instance, as long as the instance takes <5 seconds to respond and returns a successful response code, the instance is added to a list of available instances for that particular service. If not, it is discarded until the next update period.

Farside's routing is very minimal, with only the following routes:

  • /
    • The app home page, displaying all live instances for every service
  • /ping
    • A passthrough "ping" to redis to ensure both app and redis are working
  • /:service/*glob
    • The main endpoint for redirecting a user to a working instance of a particular service with the specified path
    • Ex: /libreddit/r/popular would navigate to <libreddit instance URL>/r/popular
      • If the service provided is actually a URL to a "parent" service (i.e. "youtube.com" instead of "piped" or "invidious"), Farside will determine the correct frontend to use for the specified URL.
    • Note that a path is not required. /libreddit for example will still redirect the user to a working libreddit instance
  • /_/:service/*glob
    • Achieves the same redirect as the main /:service/*glob endpoint, but preserves a short landing page in the browser's history to allow quickly jumping between instances by navigating back.
    • Ex: /_/nitter -> nitter instance A -> (navigate back one page) -> nitter instance B -> ...
    • Note: Uses Javascript to preserve the page in history

When a service is requested with the /:service/... endpoint, Farside requests the list of working instances from Redis and returns a random one from the list and adds that instance as a new entry in Redis to remove from subsequent requests for that service. For example:

A user navigates to /nitter and is redirected to nitter.net. The next user to request /nitter will be guaranteed to not be directed to nitter.net, and will instead be redirected to a separate (random) working instance. That instance will now take the place of nitter.net as the "reserved" instance, and nitter.net will be returned to the list of available Nitter instances.

This "reserving" of previously chosen instances is performed in an attempt to ensure better distribution of traffic to available instances for each service.

Farside also has built-in IP ratelimiting for all requests, enforcing only one request per second per IP.

Development

  • Install redis
  • Install elixir
  • (on Debian systems) Install erlang-dev
  • Start redis: redis-server
  • Install dependencies: mix deps.get
  • Initialize redis contents: mix run -e Farside.Instances.sync
  • Run Farside: mix run --no-halt
    • Uses localhost:4001

Environment Variables

Name Purpose
FARSIDE_TEST If enabled, bypasses the instance availability check and adds all instances to the pool.
FARSIDE_PORT The port to run Farside on (default: 4001)
FARSIDE_REDIS_PORT The Redis server port to use (default: 6379, same as the default for Redis)
FARSIDE_SERVICES_JSON The "services" JSON file to use for selecting instances (default: services.json)