Compare commits
20 Commits
8a3ca81731
...
f8ab522505
Author | SHA1 | Date |
---|---|---|
Nicolas Constant | f8ab522505 | |
Nicolas Constant | 8f42032512 | |
Nicolas Constant | 2542258ce4 | |
Nicolas Constant | 8bbbe037c4 | |
Nicolas Constant | 0c2acc3d7a | |
Nicolas Constant | 79ceab82b6 | |
Nicolas Constant | 8b1a61c197 | |
Nicolas Constant | 8897b8838d | |
Nicolas Constant | 4d365e2043 | |
Elan Hasson | d08caf3684 | |
Nicolas Constant | 86c852b8a8 | |
Nicolas Constant | 1922b7dfc8 | |
Nicolas Constant | 2880de9dda | |
nemobis | 6df0529d0b | |
Nicolas Constant | ed3faab924 | |
Nicolas Constant | 4e9fec1a46 | |
Nicolas Constant | d59e89a901 | |
Nicolas Constant | e21eacd0f7 | |
Nicolas Constant | a21b493910 | |
Nicolas Constant | 22b0d6da84 |
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
You will need a Twitter API key to make BirdsiteLIVE working. First create an **Standalone App** in the [Twitter developer portal](https://developer.twitter.com/en/portal/projects-and-apps) and retrieve the API Key and API Secret Key.
|
You will need a Twitter API key to make BirdsiteLIVE working. First create an **Standalone App** in the [Twitter developer portal](https://developer.twitter.com/en/portal/projects-and-apps) and retrieve the API Key and API Secret Key.
|
||||||
|
|
||||||
|
Please make sure you are using a **Standalone App** API Key and not a **Project App** API Key (that will NOT work with BirdsiteLIVE), if you don't see the **Standalone App** section, you might need to [apply for Elevated Access](https://developer.twitter.com/en/portal/products/elevated) as described in the [API documentation](https://developer.twitter.com/en/support/twitter-api/developer-account).
|
||||||
|
|
||||||
|
|
||||||
## Server prerequisites
|
## Server prerequisites
|
||||||
|
|
||||||
Your instance will need [docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed and working.
|
Your instance will need [docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed and working.
|
||||||
|
@ -116,7 +119,7 @@ sudo certbot --nginx -d {your-domain-name.com}
|
||||||
|
|
||||||
Make sure you're redirecting all traffic to https when asked.
|
Make sure you're redirecting all traffic to https when asked.
|
||||||
|
|
||||||
Finally check that the auto-revewal will work as espected:
|
Finally check that the auto-renewal will work as espected:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo certbot renew --dry-run
|
sudo certbot renew --dry-run
|
||||||
|
@ -183,6 +186,32 @@ services:
|
||||||
+ command: --interval 300
|
+ command: --interval 300
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## IP Whitelisting
|
||||||
|
|
||||||
|
If you want to use the IP Whitelisting functionality (see related [variable](https://github.com/NicolasConstant/BirdsiteLive/blob/master/VARIABLES.md)) and you are using the nginx reverse proxy set as before, please add the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo nano /etc/nginx/sites-enabled/{your-domain-name.com}
|
||||||
|
```
|
||||||
|
|
||||||
|
``` diff
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {your-domain-name.com};
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:5000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection keep-alive;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
+ proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## More options
|
## More options
|
||||||
|
|
||||||
You can find more options available [here](https://github.com/NicolasConstant/BirdsiteLive/blob/master/VARIABLES.md)
|
You can find more options available [here](https://github.com/NicolasConstant/BirdsiteLive/blob/master/VARIABLES.md)
|
||||||
|
|
|
@ -8,15 +8,15 @@ BirdsiteLIVE is an ActivityPub bridge from Twitter, it's mostly a pet project/pl
|
||||||
|
|
||||||
## State of development
|
## State of development
|
||||||
|
|
||||||
The code is pretty messy and far from a good state, since it's a playground for me the aim was to understand some AP concepts, not provide a good state-of-the-art codebase. But I might refactor it to make it cleaner.
|
The code is pretty messy and far from a good state, since it's a playground for me the aim was to understand some AP concepts, not to provide a good state-of-the-art codebase. But I might refactor it to make it cleaner.
|
||||||
|
|
||||||
## Official instance
|
## Official instance
|
||||||
|
|
||||||
You can find an official (and temporary) instance here: [beta.birdsite.live](https://beta.birdsite.live). This instance can disapear at any time, if you want a long term instance you should install your own or use another one.
|
There's none! Please read [here why I've stopped it](https://write.as/nicolas-constant/closing-the-official-bsl-instance).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
I'm providing a [docker build](https://hub.docker.com/r/nicolasconstant/birdsitelive). To install it on your own server, please follow [those instructions](https://github.com/NicolasConstant/BirdsiteLive/blob/master/INSTALLATION.md). More [options](https://github.com/NicolasConstant/BirdsiteLive/blob/master/VARIABLES.md) are also available.
|
I'm providing a [docker build](https://hub.docker.com/r/nicolasconstant/birdsitelive) (linux/amd64 only). To install it on your own server, please follow [those instructions](https://github.com/NicolasConstant/BirdsiteLive/blob/master/INSTALLATION.md). More [options](https://github.com/NicolasConstant/BirdsiteLive/blob/master/VARIABLES.md) are also available.
|
||||||
|
|
||||||
Also a [CLI](https://github.com/NicolasConstant/BirdsiteLive/blob/master/BSLManager.md) is available for adminitrative tasks.
|
Also a [CLI](https://github.com/NicolasConstant/BirdsiteLive/blob/master/BSLManager.md) is available for adminitrative tasks.
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ If both whitelisting and blacklisting are set, only the whitelisting will be act
|
||||||
* `Instance:FailingTwitterUserCleanUpThreshold` (default: 700) set the max allowed errors (due to a banned/deleted/private account) from a Twitter Account retrieval before auto-removal. (by default an account is called every 15 mins)
|
* `Instance:FailingTwitterUserCleanUpThreshold` (default: 700) set the max allowed errors (due to a banned/deleted/private account) from a Twitter Account retrieval before auto-removal. (by default an account is called every 15 mins)
|
||||||
* `Instance:FailingFollowerCleanUpThreshold` (default: 30000) set the max allowed errors from a Follower (Fediverse) Account before auto-removal. (often due to account suppression, instance issues, etc)
|
* `Instance:FailingFollowerCleanUpThreshold` (default: 30000) set the max allowed errors from a Follower (Fediverse) Account before auto-removal. (often due to account suppression, instance issues, etc)
|
||||||
* `Instance:UserCacheCapacity` (default: 10000) set the caching limit of the Twitter User retrieval. Must be higher than the number of synchronized accounts on the instance.
|
* `Instance:UserCacheCapacity` (default: 10000) set the caching limit of the Twitter User retrieval. Must be higher than the number of synchronized accounts on the instance.
|
||||||
|
* `Instance:IpWhiteListing` IP Whitelisting (separated by `;`), prevent usage of the instance from other IPs than those provided (if provided).
|
||||||
|
|
||||||
# Docker Compose full example
|
# Docker Compose full example
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,6 @@
|
||||||
public int FailingFollowerCleanUpThreshold { get; set; } = -1;
|
public int FailingFollowerCleanUpThreshold { get; set; } = -1;
|
||||||
|
|
||||||
public int UserCacheCapacity { get; set; }
|
public int UserCacheCapacity { get; set; }
|
||||||
|
public string IpWhiteListing { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
using BirdsiteLive.Common.Settings;
|
||||||
|
using BirdsiteLive.Domain.Tools;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BirdsiteLive.Middlewares
|
||||||
|
{
|
||||||
|
public class IpWhitelistingMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger<IpWhitelistingMiddleware> _logger;
|
||||||
|
private readonly byte[][] _safelist;
|
||||||
|
private readonly bool _ipWhitelistingSet;
|
||||||
|
|
||||||
|
public IpWhitelistingMiddleware(
|
||||||
|
RequestDelegate next,
|
||||||
|
ILogger<IpWhitelistingMiddleware> logger,
|
||||||
|
InstanceSettings instanceSettings)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(instanceSettings.IpWhiteListing))
|
||||||
|
{
|
||||||
|
var ips = PatternsParser.Parse(instanceSettings.IpWhiteListing);
|
||||||
|
_safelist = new byte[ips.Length][];
|
||||||
|
for (var i = 0; i < ips.Length; i++)
|
||||||
|
{
|
||||||
|
_safelist[i] = IPAddress.Parse(ips[i]).GetAddressBytes();
|
||||||
|
}
|
||||||
|
_ipWhitelistingSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_next = next;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext context)
|
||||||
|
{
|
||||||
|
if (_ipWhitelistingSet)
|
||||||
|
{
|
||||||
|
var remoteIp = context.Connection.RemoteIpAddress;
|
||||||
|
|
||||||
|
var forwardedIp = context.Request.Headers.FirstOrDefault(x => x.Key == "X-Real-IP").Value.ToString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(forwardedIp))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Redirected IP address detected");
|
||||||
|
remoteIp = IPAddress.Parse(forwardedIp);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogDebug("Request from Remote IP address: {RemoteIp}", remoteIp);
|
||||||
|
|
||||||
|
var bytes = remoteIp.GetAddressBytes();
|
||||||
|
var badIp = true;
|
||||||
|
foreach (var address in _safelist)
|
||||||
|
{
|
||||||
|
if (address.SequenceEqual(bytes))
|
||||||
|
{
|
||||||
|
badIp = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (badIp)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _next.Invoke(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ using BirdsiteLive.Common.Structs;
|
||||||
using BirdsiteLive.DAL.Contracts;
|
using BirdsiteLive.DAL.Contracts;
|
||||||
using BirdsiteLive.DAL.Postgres.DataAccessLayers;
|
using BirdsiteLive.DAL.Postgres.DataAccessLayers;
|
||||||
using BirdsiteLive.DAL.Postgres.Settings;
|
using BirdsiteLive.DAL.Postgres.Settings;
|
||||||
|
using BirdsiteLive.Middlewares;
|
||||||
using BirdsiteLive.Models;
|
using BirdsiteLive.Models;
|
||||||
using BirdsiteLive.Twitter;
|
using BirdsiteLive.Twitter;
|
||||||
using BirdsiteLive.Twitter.Tools;
|
using BirdsiteLive.Twitter.Tools;
|
||||||
|
@ -18,6 +19,7 @@ using Microsoft.AspNetCore.HttpsPolicy;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace BirdsiteLive
|
namespace BirdsiteLive
|
||||||
{
|
{
|
||||||
|
@ -132,6 +134,9 @@ namespace BirdsiteLive
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
var instanceSettings = Configuration.GetSection("Instance").Get<InstanceSettings>();
|
||||||
|
app.UseMiddleware<IpWhitelistingMiddleware>(instanceSettings);
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapControllerRoute(
|
endpoints.MapControllerRoute(
|
||||||
|
|
Loading…
Reference in New Issue