简体中文 / [English]


Running Your Own ISP at Home Part.2 - Announcing IP Blocks (BGP Session & BIRD)

 

This article is currently an experimental machine translation and may contain errors. If anything is unclear, please refer to the original Chinese version. I am continuously working to improve the translation.

Introduction

In the previous blog post, we successfully registered our own ASN with the LIR and leased (or were granted) a block of IPv6 addresses.

In this article, we’re going to make that IP block reachable from any internet-connected machine around the world.

BGP Sessions

In theory, we need to establish BGP sessions with border routers in other Autonomous Systems (AS) via the BGP protocol, exchanging information about our IP ranges.

However, as a brand-new micro “ISP”, we don’t actually own any physical infrastructure. After all, most real ISPs spend their time laying cables all over the globe, so other operators naturally have no incentive to let us piggyback on their networks for free.

In fact, BGP relationships between two parties are typically categorized into three types based on how they handle imported and exported routes: upstream, downstream, and peer (mutual interconnection).

  1. Upstream: Provides us with routes to the entire Internet (all other ASes), and propagates our announced routes to its own upstreams and peers.
  2. Downstream: The opposite of upstream — we provide all known routes to the downstream, and help propagate their announced routes to our peers and upstreams.
  3. Peer: Only shares routing information within their own AS, and only propagates our announced routes within their AS.

Typically, downstreams pay their upstreams (usually based on bandwidth) for access to physical infrastructure — this kind of connection is known as transit. Peer connections, on the other hand, represent cooperative relationships between equal-level ISPs and are generally settlement-free, known as peering.

So to achieve our goal in this article, the most practical way is to find an existing upstream. The upstream will propagate our announced routes to their own upstreams or peers until they reach Tier 1 ISPs, which interconnect via peering to exchange all known routes, ultimately linking the entire Internet.

As for how to set up peering with others — we’ll leave that for the next blog post due to length constraints.

Finding an Upstream

Major carriers often have presence in data centers. If you have a dedicated server hosted in such a facility, you can directly contact the carrier to purchase bandwidth and IP transit services. Of course, this entire process tends to be quite expensive (just think about the insane pricing of enterprise leased lines in China, or the hassle and cost of setting up a server overseas).

Fortunately, some VPS providers also offer BGP session services (essentially IP transit under a different name), such as Vultr, v.ps, or BuyVM. There are also BGP tunnel services that establish BGP sessions over tunnels to provide transit — some of which are even free.

You can also try searching for providers on BGP Services.


Configuration methods vary by provider. Here, I’ll use v.ps as an example: you need to purchase at least a three-month subscription to a VPS in the Düsseldorf region (totaling 22.95 EUR), which comes with free LocIX access and BGP session setup. (Note: BGP session pricing varies by region on this provider — only Germany offers free LocIX access.)

After purchasing, submit a support ticket. The support team will ask you to register on PeeringDB and send a Letter of Authorization (LoA) to a specified email address. Once done, your BGP session and LocIX access will be configured.

Announcing Your IP Block

At this point, you should have received the following information from your upstream:

  • Upstream’s ASN
  • Upstream’s IP address
  • (Optional) MD5 password

Now that we’ve found an upstream, it’s time to configure our BGP client — BIRD. BIRD is a BGP implementation for clients. For a detailed guide, check out this excellent BGP tutorial by Soha.

I’m using Debian Bookworm, which is relatively recent, so I installed BIRD directly via apt install bird2. For older distributions, it’s recommended to compile from source as per the BIRD documentation.

My ASN is 214775, and I want to announce 2a14:7c0:4d00::/40.
My upstream, xTom, has ASN 3204, IPv6 address 2a03:d9c0:2000::5, and my VPS’s IPv6 address is 2a03:d9c0:2000::1f7. The MD5 password is 114514. My configuration file looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
log syslog all;

router id 185.254.74.126; # Public IPv4 address of the VPS
define ASN=214775; # My ASN
define OWNIPv6s=[2a14:7c0:4d00::/40]; # My IPv6 address block

# The device protocol must be present; otherwise, BIRD won't automatically get interface info from the kernel, breaking direct protocol and next-hop resolution
protocol device {}

# The kernel protocol is used to export routing tables into the kernel
protocol kernel {
ipv6 {
export all; # Export all IPv6 routes to the system routing table
};
}

# Static protocol for defining static routes
protocol static static_v6 {
ipv6;
route 2a14:7c0:4d00::/40 unreachable; # Announce the 2a14:7c0:4d00::/40 block, initially set as unreachable
}

filter export_filter_v6 {
if net ~ OWNIPv6s then accept; # Accept if the prefix is within OWNIPv6s
reject; # Reject everything else
}

filter import_filter_v6 {
if net ~ [::/0] then reject; # Reject default route
accept; # Accept all other routes
}

protocol bgp bgp_xtom_v6 {
local 2a03:d9c0:2000::1f7 as ASN; # Local address and ASN
neighbor 2a03:d9c0:2000::5 as 3204; # Neighbor address and ASN
ipv6 { # Specify the protocol to run on this BGP neighbor
import filter import_filter_v6; # Import filter
export filter export_filter_v6; # Export filter
export limit 10; # Limit number of exported prefixes (adjust as needed) to prevent session flooding due to misconfiguration
};
password "114514"; # Not me being cheeky — v.ps actually gave me this password... Remove this line if no password is set
graceful restart; # Enable graceful restart to prevent route withdrawal and service disruption during BIRD restarts
}

You can modify my config as a template (though I still recommend reading Soha’s guide first). Once done, save it to /etc/bird/bird.conf and restart BIRD: systemctl restart bird.

Run birdc show protocols all to check the status of all protocols. You should see the BGP session is established, importing 204,923 IPv6 routes from the internet, and exporting 1 route of our own:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
bgp_xtom_v6 BGP        ---        up     08:00:21.885  Established   
BGP state: Established
Neighbor address: 2a03:d9c0:2000::5
Neighbor AS: 3204
Local AS: 214775
Neighbor ID: 62.133.35.43
Local capabilities
Multiprotocol
AF announced: ipv6
Route refresh
Graceful restart
Restart time: 120
AF supported: ipv6
AF preserved:
4-octet AS numbers
Enhanced refresh
Long-lived graceful restart
Neighbor capabilities
Multiprotocol
AF announced: ipv6
Route refresh
Graceful restart
4-octet AS numbers
Enhanced refresh
Long-lived graceful restart
Session: external AS4
Source address: 2a03:d9c0:2000::1f7
Hold timer: 218.652/240
Keepalive timer: 17.453/80
Channel ipv6
State: UP
Table: master6
Preference: 100
Input filter: import_filter_v6
Output filter: export_filter_v6
Export limit: 10
Action: disable
Routes: 204923 imported, 1 exported, 204923 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 206278 0 0 63 206215
Import withdraws: 170 0 --- 27 143
Export updates: 206216 206215 0 --- 1
Export withdraws: 143 --- --- --- 0
BGP Next hop: 2a03:d9c0:2000::1f7 fe80::12b8:55ff:fe21:8e9

Now run birdc show route to view BIRD’s internal routing table, and ip -6 route to see that BIRD has injected all IPv6 routes into the system (expect a lot of output).

Propagation and convergence of your announced prefix across the globe may take some time. Feel free to do something else for a bit — maybe even stand up and stretch.

Half an hour later, head over to BGP Tools. Search for your announced prefix 2a14:7c0:4d00::/40. Under the Connectivity tab, you’ll see a visual representation of current reachability. If this is your first time announcing an AS, different upstreams may update their filters at different speeds — actual propagation could take up to 24 hours.

Real-time connectivity: xTom is our upstream, and we can see their upstreams tooReal-time connectivity: xTom is our upstream, and we can see their upstreams too

Configuring the Network Interface

We’ve now successfully announced 2a14:7c0:4d00::/40.

Try pinging an IP within this block. Based on our BIRD configuration, the server will respond with ICMP destination unreachable. (Note: I found that ping6 on macOS doesn’t properly display this “Destination unreachable” message — ping -6 on Linux shows “Destination unreachable: no route”, and Windows ping correctly reports “Destination host unreachable”).

At this point, traffic from around the world destined for 2a14:7c0:4d00::/40 is being routed to our VPS — but our VPS is currently configured to do nothing and just return “unreachable”. A few small tweaks, and we can start serving traffic:

1
2
3
4
5
6
# Create a dummy network interface
ip link add dev dummy0 type dummy
ip link set dummy0 up

# Assign a preferred IP from your block
ip addr add dev dummy0 2a14:7c0:4d00::1

Once done, you should be able to ping 2a14:7c0:4d00::1 from your local machine.

Global ping test results from ping.peGlobal ping test results from ping.pe

Now, we can run any service on the VPS and let others access it via 2a14:7c0:4d00::1. For example, I started a simple HTTP server with: python3 -m http.server -b :: 80.

Successfully accessing the hosted HTTP serverSuccessfully accessing the hosted HTTP server

From within the VPS, we can also use 2a14:7c0:4d00::1 as our source address to access external websites(achieving real-name internet access):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@s39230 ~ # curl --interface 2a14:7c0:4d00::1 -6 www.cloudflare.com/cdn-cgi/trace
fl=910f33
h=www.cloudflare.com
ip=2a14:7c0:4d00::1
ts=1725599416.24
visit_scheme=http
uag=curl/7.88.1
colo=DUS
sliver=none
http=http/1.1
loc=IL
tls=off
sni=off
warp=off
gateway=off
rbi=off
kex=none

Summary

In this blog post, we successfully announced our IP block, making our autonomous system visible to the entire Internet.

The next post will cover how to establish peering relationships with other networks.

This article is licensed under the CC BY-NC-SA 4.0 license.

Author: lyc8503, Article link: https://blog.lyc8503.net/en/post/asn-2-bgp-session/
If this article was helpful or interesting to you, consider buy me a coffee¬_¬
Feel free to comment in English below o/