A smart redirecting gateway for various frontend services
Go to file
Ben Busby d4581797e7
Allow bypassing app router with `FARSIDE_NO_ROUTER`
Setting the aforementioned env var skips creation of the app router,
which is useful for running update.exs when the main app is already
running (otherwise there's a port conflict).
2021-11-15 20:09:34 -07:00
.github/workflows Test for valid service redirects 2021-11-10 11:47:03 -07:00
config Allow bypassing app router with `FARSIDE_NO_ROUTER` 2021-11-15 20:09:34 -07:00
img Convert logo to SVG 2021-11-12 17:04:34 -07:00
lib Allow bypassing app router with `FARSIDE_NO_ROUTER` 2021-11-15 20:09:34 -07:00
test Fix formatting 2021-11-12 14:40:05 -07:00
.formatter.exs Setup basic Plug.Router framework for serving requests 2021-10-22 18:28:12 -06:00
.gitignore Write results of update script to file for debugging 2021-10-22 18:07:59 -06:00
LICENSE Initial commit 2021-10-21 15:50:04 -06:00
README.md Allow bypassing app router with `FARSIDE_NO_ROUTER` 2021-11-15 20:09:34 -07:00
index.eex Display list of available instances on home page 2021-11-08 17:08:19 -07:00
install-crontab.sh Install crontab w/ script 2021-11-15 16:44:26 -07:00
mix.exs Fix formatting 2021-11-12 14:40:05 -07:00
mix.lock Throttle incoming requests to 1/sec per ip 2021-11-12 14:34:36 -07:00
services.json Add searx instances to services.json 2021-11-15 17:51:29 -07:00
update.exs Install crontab w/ script 2021-11-15 16:44:26 -07:00
update.sh Allow bypassing app router with `FARSIDE_NO_ROUTER` 2021-11-15 20:09:34 -07:00

README.md

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

Service Page Farside Link
Libreddit /r/popular https://farside.link/libreddit/r/popular
Nitter User Profile https://farside.link/nitter/josevalim
Invidious Home Page https://farside.link/invidious
Bibliogram User Profile https://farside.link/bibliogram/u/kbdfans
Whoogle Search "Elixir" https://farside.link/whoogle/search?q=elixir
Searx Search "Redis" https://farside.link/searx/search?q=redis

How It Works

The app runs in a container that periodically (default every 5 minutes) queries all instances for services defined in services.json. For each instance, as long as the instance takes <5 seconds to respond and returns a 200 status 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
    • Note that a path is not required. /libreddit for example will still redirect the user to a working libreddit instance

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
  • Start redis: redis-server /usr/local/etc/redis.conf
  • Install dependencies: mix deps.get
  • Initialize redis contents: mix run update.exs
  • Run Farside: mix run --no-halt
    • Uses localhost:4001

Environment Variables

Name Purpose
FARSIDE_TEST If enabled, skips the instance availability check in update.exs.
FARSIDE_NO_ROUTER If enabled, skips creation of the router. Useful for running update.exs with mix run when the app is already running.