space-wizards / space-station-14

A multiplayer game about paranoia and chaos on a space station. Remake of the cult-classic Space Station 13.
https://spacestation14.com
MIT License
2.74k stars 3.48k forks source link

ASN ban support: Part 1 #25204

Open Chief-Engineer opened 9 months ago

Chief-Engineer commented 9 months ago

An ASN is an unsigned 32 bit integer. This issue is resolved by implementing the following:

  1. ability for an ASN ban to exist in the database
  2. when a player connects, their IP address is passed to a method that is expected to return an ASN which is then checked to see if it matches a ban entry and is handled accordingly

ASN ban entires

ASN bans should support all the same things that current bans do, excluding the ban target options. This means things like ban reasons, expirations, unbans, flags, and a record of who placed the ban and when.

I'm not sure if there's a good way to expand current bans to support ASN bans rather than creating a new ban type or something, but the vast majority of bans will not include an ASN, and no ban that includes an IP component will include an ASN. Putting AS100 in the IP field of a ban to ban ASN 100 would be great, but I'm pretty sure that's not possible on the database end of things.

Getting ASNs

The actual implementation of the method that translates IP to ASN can be done in many different ways, so it's not included in this issue. It is probably a good idea to build the system in a way where different options are available through cvars, similar to how SS14 can use SQLite or PostgreSQL.

Chief-Engineer commented 9 months ago

Will make an issue for part 2 when this issue is done or if someone expresses interest, but I'm fairly certain that this issue includes all the information needed to complete it, regardless of the specific implementation of part 2

nicewrld commented 7 months ago

Curious: What's the use case to ban an entire AS?

(this is my first attempt to contribute, if I'm doing something dumb lmk)

AS's don't necessarily persistently own, or even always announce, IP ranges. Because of this, there has to be some mechanism to update this data when we use it. I wasn't able to find an easily-accessible source for the authoritative owners of individual IP ranges, but was able to find [a good source](https://thyme.apnic.net/current/) of what CIDR blocks are currently being announced by what ASs.

I think this is probably a good enough source of data for our uses since it's simple to consume, updated daily, and removes a lot of the complexity for us. Using this comes with the assumptions that you intend to ban any IP addresses that an AS is advertising, so that as they buy/sell IP ranges (or leases end etc.) that those get updated periodically on our end. This also means that if a BGP hijack was happening during the time we updated our entries, the IPs hijacked would 'belong' to another AS.

I'm not doing it now because i'm lazy, but if the above assumptions are not good enough you could probably go deeper and find something from RIPE. https://ris.ripe.net/docs/mrt is a direction.

I did some work while daydrinking on throwing the data from the first source into sqlite/pg, so I can do some work on the actual lookup portion next. It's my first time in at least a decade or so using C#, so we'll see how it goes. I figured we would want the query to be happening locally to the server for privacy, license, cost, and latency reasons, so that's the path I'm headed.

Chief-Engineer commented 7 months ago

Curious: What's the use case to ban an entire AS?

We currently ban IP ranges that belong to datacenters to help prevent ban evasion. Since we ban the ranges directly, those bans do not automatically update if the owner changes. Operators can also own multiple non-contiguous ranges. AS bans allow us to do things like ban many AWS ranges in a way where the ranges affected will be updated if ranges leave or come into the AS.

I have a few different options for how we can get the data and have it locally, but I haven't talked to anyone much about which of those options we want to go with. This issue is only the first part of a full implementation, and is only to create:

  1. the ability for an ASN ban to exist in the database (meaning that the database can hold ban info for an AS)
  2. when a player connects, their IP address is passed to a method that is expected to return an ASN (the method will not actually return an ASN, because that logic will not have been implemented yet, instead it should behave as if the lookup failed, which should essentially bypass the next step) which is then checked to see if it matches a ban entry and is handled accordingly