<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Artem Kohanevich</title>
    <description>The latest articles on DEV Community by Artem Kohanevich (@kohanevich).</description>
    <link>https://dev.to/kohanevich</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3615451%2Ffc20ad4b-093a-49b2-9988-8e2473378698.png</url>
      <title>DEV Community: Artem Kohanevich</title>
      <link>https://dev.to/kohanevich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kohanevich"/>
    <language>en</language>
    <item>
      <title>Leasing IPv4 for a Colocation Facility: Registry Objects, ROAs, and the /24 Floor</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Sat, 12 Sep 2026 10:13:47 +0000</pubDate>
      <link>https://dev.to/kohanevich/leasing-ipv4-for-a-colocation-facility-registry-objects-roas-and-the-24-floor-apm</link>
      <guid>https://dev.to/kohanevich/leasing-ipv4-for-a-colocation-facility-registry-objects-roas-and-the-24-floor-apm</guid>
      <description>&lt;p&gt;Leasing an IPv4 block is commercially simple and operationally not. The contract takes a week. Getting the block to carry traffic for your renters - and keeping the registry consistent while it does - involves objects in three different systems, two of which you do not control.&lt;/p&gt;

&lt;p&gt;This post is the technical view. It assumes you know what BGP and RPKI are and skips the explanation of why IPv4 is scarce.&lt;/p&gt;

&lt;h2&gt;
  
  
  The distribution problem
&lt;/h2&gt;

&lt;p&gt;Most parties leasing IPv4 consume it directly: one block, one announcement, one operator. A colocation facility is a distribution layer. You take space from an owner and hand portions of it to renters running their own equipment.&lt;/p&gt;

&lt;p&gt;That introduces a constraint that shapes everything else:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The global routing table will not accept anything longer than a /24.&lt;/strong&gt; Operators filter it. So a renter who needs 16 addresses cannot announce their /28 themselves - it has to be announced by you, from your ASN, as part of a covering /24.&lt;/p&gt;

&lt;p&gt;This splits your renters into two categories before you allocate anything:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Renter needs&lt;/th&gt;
&lt;th&gt;Announced by&lt;/th&gt;
&lt;th&gt;ROA required&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Less than a /24&lt;/td&gt;
&lt;td&gt;Your ASN, inside a covering prefix&lt;/td&gt;
&lt;td&gt;One, covering the whole block, your ASN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A full /24 or more, routed by you&lt;/td&gt;
&lt;td&gt;Your ASN&lt;/td&gt;
&lt;td&gt;One, your ASN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A full /24 or more, their own ASN&lt;/td&gt;
&lt;td&gt;Their ASN&lt;/td&gt;
&lt;td&gt;Separate ROA naming their ASN&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The third row is the one that needs negotiating with the owner in advance, because it means they publish a ROA for an ASN that is neither yours nor theirs. Some owners will not do it. Find out before you sell that cabinet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the owner has to give you
&lt;/h2&gt;

&lt;p&gt;Three artefacts, and none of them are optional.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Letter of Authorisation
&lt;/h3&gt;

&lt;p&gt;A signed document from the registered owner authorising your ASN to announce the block. Your upstreams will ask for it before they accept the prefix. Check the expiry date matches your lease term - a LOA that expires before your contract does will cause an outage nobody diagnoses quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A ROA in the RPKI
&lt;/h3&gt;

&lt;p&gt;Published by the owner under their RIR account. Validators then treat your announcement as &lt;code&gt;valid&lt;/code&gt; rather than &lt;code&gt;notFound&lt;/code&gt;, and a growing share of the internet drops &lt;code&gt;invalid&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The parameter to pay attention to is &lt;code&gt;maxLength&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;192.0.2.0/24&lt;/span&gt;
&lt;span class="na"&gt;asn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;AS64496&lt;/span&gt;
&lt;span class="na"&gt;maxLength&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;maxLength&lt;/code&gt; does not have to equal the prefix length. A wider value is valid and is sometimes genuinely needed - if you intend to deaggregate a /23 into two /24s announced separately, a &lt;code&gt;maxLength&lt;/code&gt; of 24 on the covering /23 is what makes that work.&lt;/p&gt;

&lt;p&gt;But RFC 9319 recommends against setting it wider than you actually need. An overly permissive &lt;code&gt;maxLength&lt;/code&gt; makes forged-origin sub-prefix announcements validate cleanly, which is exactly the attack RPKI is supposed to stop. Ask for the specific values you need, not a blanket maximum.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Registry objects
&lt;/h3&gt;

&lt;p&gt;RIPE is explicit that only allocations and assignments registered in the RIPE Database count as valid - registering the object is the final step of making an assignment, not paperwork that follows it. ARIN applies the same principle through SWIP for any reassignment of a /29 or larger.&lt;/p&gt;

&lt;p&gt;In a lease, the block sits under the owner's registration. So the objects describing your renters are created under &lt;strong&gt;their&lt;/strong&gt; maintainer, or through their sponsoring LIR. That has a direct consequence for your provisioning pipeline, covered below.&lt;/p&gt;

&lt;p&gt;You will also likely want a &lt;code&gt;route:&lt;/code&gt; object in the RIPE Database (or the relevant IRR), since plenty of upstreams still build prefix filters from IRR data rather than RPKI alone:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;192.0.2.0/24&lt;/span&gt;
&lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;AS64496&lt;/span&gt;
&lt;span class="na"&gt;mnt-by&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;MAINT-EXAMPLE&lt;/span&gt;
&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;RIPE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The object hierarchy
&lt;/h2&gt;

&lt;p&gt;For a leased &lt;code&gt;/24&lt;/code&gt; where you assign sub-blocks to renters, the RIPE Database structure looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192.0.2.0/24        ALLOCATED PA        (owner's LIR)
├── 192.0.2.0/26    ASSIGNED PA         renter A
├── 192.0.2.64/27   ASSIGNED PA         renter B
├── 192.0.2.96/27   ASSIGNED PA         renter C
└── 192.0.2.128/25  LIR-PARTITIONED PA  held for allocation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two status values worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LIR-PARTITIONED&lt;/code&gt;&lt;/strong&gt; marks space reserved but not yet in use. It is explicitly &lt;em&gt;not&lt;/em&gt; counted as used - when the addresses are deployed, a more specific &lt;code&gt;inetnum&lt;/code&gt; has to be created. Useful for holding contiguous space against a renter's growth without misrepresenting utilisation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SUB-ALLOCATED PA&lt;/code&gt;&lt;/strong&gt; exists for delegating a range to a downstream operator who will make their own assignments within it. Whether you can use it depends entirely on how the owner has structured things and what your lease permits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each &lt;code&gt;inetnum&lt;/code&gt; carries an &lt;code&gt;abuse-c&lt;/code&gt; reference. This determines where complaints about traffic from that range are delivered. Decide deliberately whether that is your NOC or the renter's - routing abuse mail to a renter who ignores it will cost you the block's reputation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provisioning latency is now a dependency
&lt;/h2&gt;

&lt;p&gt;Here is the practical consequence of the block being registered to someone else.&lt;/p&gt;

&lt;p&gt;Your provisioning flow for a new renter probably looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. allocate sub-block in IPAM
2. configure interface / VLAN
3. create inetnum object          ← owner's maintainer
4. request reverse DNS delegation ← LIR only
5. announce / verify reachability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Steps 3 and 4 are not yours. RIPE only accepts reverse delegation requests from LIRs, so &lt;code&gt;in-addr.arpa&lt;/code&gt; records for your renters route through the owner too. If a renter runs mail, missing PTR records will hurt them immediately and they will open a ticket with you, not with the owner.&lt;/p&gt;

&lt;p&gt;Three questions to settle contractually before the first provision:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Delegated maintainer access, or request-based?&lt;/strong&gt; Direct &lt;code&gt;mnt-by&lt;/code&gt; access on the sub-objects removes a human from your critical path. Ask for it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What is the committed turnaround on a request?&lt;/strong&gt; 48 hours is workable. Two weeks silently becomes your provisioning SLA.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who handles &lt;code&gt;in-addr.arpa&lt;/code&gt;?&lt;/strong&gt; Including the delegation for renters who need custom PTRs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Reputation is a shared fate within the prefix
&lt;/h2&gt;

&lt;p&gt;Blocklists operate on ranges. One renter in a /24 generating spam or scanning traffic can get the whole prefix listed, and delisting takes days to weeks during which your other renters in that block see degraded mail delivery.&lt;/p&gt;

&lt;p&gt;Pre-lease diligence is cheap and entirely public:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# registry record and current holder&lt;/span&gt;
whois &lt;span class="nt"&gt;-h&lt;/span&gt; whois.ripe.net 192.0.2.0/24
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://rdap.db.ripe.net/ip/192.0.2.0/24 | jq

&lt;span class="c"&gt;# RPKI validity and announcement history&lt;/span&gt;
&lt;span class="c"&gt;# stat.ripe.net -&amp;gt; routing-history, rpki-validation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check the range against the major blocklists before signing, not after. A block with a history of listings is not automatically disqualified, but it is a price negotiation and it changes which renters you put in it.&lt;/p&gt;

&lt;p&gt;Design-level mitigations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separate prefixes by risk profile.&lt;/strong&gt; Mail-heavy renters and general hosting in different /24s where possible. Contained blast radius.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Egress rate limiting and outbound port 25 policy&lt;/strong&gt; by default, opened per renter on request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netflow-based anomaly alerting&lt;/strong&gt; on egress, so you find out before a blocklist does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A suspension clause with a short notice period&lt;/strong&gt; in the renter agreement. Your own lease almost certainly gives the owner equivalent rights against you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Renumbering on exit
&lt;/h2&gt;

&lt;p&gt;RIPE policy on provider aggregatable space is unambiguous: when a downstream operator changes provider, the PA space returns and they renumber. Leased space inherits this.&lt;/p&gt;

&lt;p&gt;Put it in the renter agreement explicitly, with the notice period and a stated migration window. A renter who has hardcoded your addresses into their configs, their DNS, and their partners' allowlists will discover the problem at the worst moment otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  BYOIP for hybrid renters
&lt;/h2&gt;

&lt;p&gt;Leased space can be brought into AWS, Azure, Google Cloud, and OVHcloud under BYOIP, which matters for renters running split deployments. Requirements are broadly consistent across providers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;/24&lt;/code&gt; or larger (none of them accept longer prefixes)&lt;/li&gt;
&lt;li&gt;a ROA authorising the provider's ASN, published by the owner&lt;/li&gt;
&lt;li&gt;a signed authorisation message, usually with an X.509 keypair and a signed &lt;code&gt;inetnum&lt;/code&gt; or ROA-derived token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The provisioning step is the slow one - expect weeks rather than days, and the owner is in the loop for the ROA. Worth scoping before a renter commits to a migration date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-signature checklist
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;[ ] LOA covers the full lease term, ASN correct
[ ] ROA parameters agreed, maxLength no wider than needed
[ ] Onward assignment to renters permitted in writing
[ ] Third-party ASN ROAs possible if a renter needs one
[ ] Delegated maintainer access, or committed turnaround
[ ] in-addr.arpa delegation path defined
[ ] abuse-c ownership decided per object
[ ] Registry and routing history checked, blocklist status clean
[ ] Abuse escalation process documented, both directions
[ ] Renumbering terms mirrored into renter agreements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of this is one conversation with the owner before signing. All of it is expensive to retrofit after you have renters in the block.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;A less registry-heavy version of this, covering the commercial side and the buy-versus-lease decision, is on the IPbnb blog: &lt;a href="https://ipbnb.com/blog/ip-address-leasing-data-centers" rel="noopener noreferrer"&gt;IP Address Leasing for Data Centers&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>infrastructure</category>
      <category>networking</category>
    </item>
    <item>
      <title>Verifying an IPv4 Block Before You Lease It: RDAP, BGP, and RPKI in Practice</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Thu, 03 Sep 2026 22:54:51 +0000</pubDate>
      <link>https://dev.to/kohanevich/verifying-an-ipv4-block-before-you-lease-it-rdap-bgp-and-rpki-in-practice-5fnl</link>
      <guid>https://dev.to/kohanevich/verifying-an-ipv4-block-before-you-lease-it-rdap-bgp-and-rpki-in-practice-5fnl</guid>
      <description>&lt;p&gt;Most "who owns this IP" tooling answers one question and presents it as the whole answer. For incident response that's usually fine. For a lease you're about to route production traffic through, it isn't.&lt;/p&gt;

&lt;p&gt;There are five separate questions, and they resolve against five different data sources:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;What the answer actually means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who is registered for the block?&lt;/td&gt;
&lt;td&gt;RDAP / RIR WHOIS&lt;/td&gt;
&lt;td&gt;Registered holder of the containing object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who is originating it now?&lt;/td&gt;
&lt;td&gt;BGP (RIPEstat, RouteViews)&lt;/td&gt;
&lt;td&gt;Origin ASN as seen by route collectors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is that origin authorized?&lt;/td&gt;
&lt;td&gt;RPKI, secondarily IRR&lt;/td&gt;
&lt;td&gt;Whether origin+prefix match a covering ROA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where is it used?&lt;/td&gt;
&lt;td&gt;Geolocation providers&lt;/td&gt;
&lt;td&gt;An estimate. Not authoritative for anything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What's its abuse history?&lt;/td&gt;
&lt;td&gt;Reputation services, plural&lt;/td&gt;
&lt;td&gt;Provider-specific, time-sensitive signals&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A holder/origin mismatch is not evidence of fraud - leasing, transit, BYOIP, and parent/subsidiary structures all produce one routinely. What matters is whether the mismatch is &lt;em&gt;accounted for&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  RDAP over WHOIS, and why
&lt;/h2&gt;

&lt;p&gt;RDAP is standardized where WHOIS isn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RFC 9082&lt;/strong&gt; - query format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 9083&lt;/strong&gt; - JSON response structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFC 9224&lt;/strong&gt; - bootstrap (IANA registry → correct RIR endpoint)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WHOIS returns registry-specific plain text. ARIN uses &lt;code&gt;NetRange&lt;/code&gt; / &lt;code&gt;OrgName&lt;/code&gt;; RIPE and APNIC use RPSL-style &lt;code&gt;inetnum&lt;/code&gt; / &lt;code&gt;descr&lt;/code&gt;. If you're parsing, you write a parser per registry. RDAP gives you consistent field names across all five RIRs.&lt;/p&gt;

&lt;p&gt;Two things RDAP does &lt;em&gt;not&lt;/em&gt; give you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Accuracy.&lt;/strong&gt; Both services read from the same registry data maintained by resource holders. A stale org name is stale in both.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A different answer than WHOIS.&lt;/strong&gt; They're views over the same records, not independent sources. Cross-checking one against the other proves nothing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One correction that comes up a lot: the January 2025 WHOIS sunset applied to gTLD registration data. RDAP became definitive for domain names on 28 January 2025, 374 gTLDs had disabled WHOIS by that September, and RDAP query volume overtook WHOIS in June 2025. &lt;strong&gt;RIR WHOIS for IP and ASN resources was unaffected and is still running in 2026.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The first pass
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# Minimum viable due diligence on an offered prefix.&lt;/span&gt;
&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"198.51.100.0/24"&lt;/span&gt;
&lt;span class="nv"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"198.51.100.10"&lt;/span&gt;

&lt;span class="c"&gt;# 1. Registry record, via RDAP bootstrap.&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://rdap.org/ip/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="s1"&gt;'{
  name, handle, type, country,
  cidr: .cidr0_cidrs,
  parent: .parentHandle,
  roles: [.entities[]? | {handle, roles}],
  events: [.events[]? | {action: .eventAction, date: .eventDate}]
}'&lt;/span&gt;

&lt;span class="c"&gt;# 2. Current origin + history.&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://stat.ripe.net/data/routing-status/data.json?resource=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.data | {visibility, first_seen, last_seen, announced_space}'&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://stat.ripe.net/data/routing-history/data.json?resource=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.data.by_origin[] | {origin, timelines}'&lt;/span&gt;

&lt;span class="c"&gt;# 3. ROA state.&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://stat.ripe.net/data/rpki-validation/data.json?resource=AS64500&amp;amp;prefix=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.data | {status, validating_roas}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;198.51.100.0/24&lt;/code&gt; is TEST-NET-2 (RFC 5737). Substitute the real prefix; don't route the example.&lt;/p&gt;

&lt;p&gt;Notes on the output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;type&lt;/code&gt;&lt;/strong&gt; distinguishes &lt;code&gt;ALLOCATION&lt;/code&gt;, &lt;code&gt;ASSIGNMENT&lt;/code&gt;, &lt;code&gt;LEGACY&lt;/code&gt;, and registry-specific values. Terminology differs per RIR - don't map ARIN semantics onto a RIPE object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;parentHandle&lt;/code&gt;&lt;/strong&gt; matters when the offered range sits under a larger allocation. RDAP returns the most specific object; the commercial relationship may live one level up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;events&lt;/code&gt;&lt;/strong&gt; gives you &lt;code&gt;registration&lt;/code&gt; and &lt;code&gt;last changed&lt;/code&gt;. A recent &lt;code&gt;last changed&lt;/code&gt; means &lt;em&gt;something&lt;/em&gt; was touched, not that every field was reverified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;cidr0_cidrs&lt;/code&gt;&lt;/strong&gt; - confirm the returned object actually contains your full offered prefix. Querying one IP and assuming the /24 inherits its status is the single most common mistake here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Persist the raw JSON with a timestamp. Registry and routing state both drift; a saved response is evidence, a screenshot isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Origin history is the interesting part
&lt;/h2&gt;

&lt;p&gt;Current origin tells you today. History tells you what you're inheriting.&lt;/p&gt;

&lt;p&gt;What to pull out of &lt;code&gt;routing-history&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every origin ASN observed, with first/last seen&lt;/li&gt;
&lt;li&gt;Gaps in announcement - dormant space is a hijack target&lt;/li&gt;
&lt;li&gt;More-specifics announced from unrelated ASNs&lt;/li&gt;
&lt;li&gt;Churn without explanation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any of these is a question for the provider, not a disqualification. But "we don't know" is itself an answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  ROA state, and what it's worth
&lt;/h2&gt;

&lt;p&gt;Three outcomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Valid    → prefix + origin ASN covered by a matching ROA,
           announcement no more specific than maxLength
Invalid  → covering ROA exists, ASN or prefix length doesn't match
NotFound → no covering ROA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Worth calibrating expectations here. RPKI coverage hit a record 67.43% of announced prefixes in June 2026 - roughly 1.07M of 1.58M routes carrying a signed ROA. Enforcement is the lagging half: measurement work cited by RIPE Labs puts full route origin validation at around 12% of ASes, with roughly 36% not validating at all.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;Valid&lt;/code&gt; means &lt;em&gt;the origin is authorized and networks that validate will accept it&lt;/em&gt;. It does not mean the announcement is safe from hijack, that the AS path is sound, or that the entity emailing you is the holder. ROV checks the rightmost AS in the path. An attacker who wants a protected prefix doesn't fight the ROA - they announce the victim's prefix with the victim's ASN at origin and prepend their own.&lt;/p&gt;

&lt;p&gt;Also worth checking &lt;code&gt;maxLength&lt;/code&gt; in the ROA. Over-permissive maxLength (RFC 9319 covers this) leaves room for more-specific announcements that still validate. If the lessor is creating a fresh ROA for your ASN, specify it exactly rather than accepting a default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reputation: scan the range, not a sample
&lt;/h2&gt;

&lt;p&gt;Registry and routing checks say nothing about deliverability or platform acceptance. Separate step, separate tooling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Spamhaus ZEN, reversed-octet DNSBL query.&lt;/span&gt;
&lt;span class="c"&gt;# Use your own resolver - public mirrors refuse queries from large resolvers,&lt;/span&gt;
&lt;span class="c"&gt;# and a sequential /24 scan will hit rate limits.&lt;/span&gt;
check_zen&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;rev
  &lt;span class="nv"&gt;rev&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'{print $4"."$3"."$2"."$1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;result
  &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;rev&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.zen.spamhaus.org"&lt;/span&gt; A&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Whole /24, not a sample.&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;0 255&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;check_zen &lt;span class="s2"&gt;"198.51.100.&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Return codes map to distinct lists, and they mean different things:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;List&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;127.0.0.2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SBL&lt;/td&gt;
&lt;td&gt;Manually researched spam source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;127.0.0.3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CSS&lt;/td&gt;
&lt;td&gt;Auto-detected low-reputation sender&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;127.0.0.4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;XBL&lt;/td&gt;
&lt;td&gt;Compromised/exploited host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;127.0.0.9&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SBL DROP&lt;/td&gt;
&lt;td&gt;Hijacked or wholly malicious allocation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;127.0.0.10/11&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PBL&lt;/td&gt;
&lt;td&gt;Policy range, shouldn't send direct-to-MX&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A PBL listing is a policy statement about the range, not an abuse finding. Treating it as equivalent to SBL will make you walk away from perfectly usable space. &lt;code&gt;127.0.0.9&lt;/code&gt; is the one that should stop a deal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One number that justifies the whole exercise:&lt;/strong&gt; a study of RIR transfer reports from 2009 to 2019 found nearly 40% of routed transferred prefixes carried at least one blacklist report, against about 6% of routed prefixes that had never been transferred. Traded space isn't inherently bad. It's a different prior.&lt;/p&gt;

&lt;h2&gt;
  
  
  The check nobody automates
&lt;/h2&gt;

&lt;p&gt;Everything above queries what the registry &lt;em&gt;says&lt;/em&gt;. None of it tells you whether the registry can &lt;em&gt;act&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That matters when a lease depends on a record change - a ROA creation, a route object update, an entity change - happening inside the lease term.&lt;/p&gt;

&lt;p&gt;AFRINIC is the working example. Board dissolved, registry under receivership from 2022-2023, address requests stalled for months with no functioning governance. A board was seated after the 2025 elections and the receiver applied to terminate receivership in October 2025, but litigation begun before and after those elections is still open, the June 2025 election was annulled and re-run, and the incoming CEO doesn't take office until January 2027.&lt;/p&gt;

&lt;p&gt;There's no API for "can this registry process my request this quarter." Ask the provider, name the RIR, get it in writing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ ] Full CIDR, RIR, proposed origin ASN, lease term, activation date
[ ] RDAP object contains the entire offered prefix (not just a sample IP)
[ ] Registered holder identified; counterparty's relationship documented
[ ] Signer authority verified via a channel the counterparty didn't supply
[ ] Current + historical BGP origins reviewed; anomalies explained
[ ] ROA plan matches agreed prefix and origin ASN, maxLength specified
[ ] IRR route object plan confirmed
[ ] Full range scanned across multiple reputation sources
[ ] Registry turnaround time for record changes confirmed in writing
[ ] Acceptance criteria + remediation deadlines in the contract
[ ] Withdrawal sequence defined for end of lease
[ ] Raw JSON responses archived with timestamps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Activation ordering matters too: old announcement withdrawn → ROA and IRR updated → new announcement started → propagation monitored. Overlapping announcements during a handover produce exactly the ambiguity you spent all this effort eliminating.&lt;/p&gt;




&lt;p&gt;Longer writeup with the field-by-field registry reading guide, the RDAP-vs-WHOIS comparison, and a green/yellow/red decision table for lease evaluation: &lt;strong&gt;&lt;a href="https://ipbnb.com/blog/who-owns-ip-address" rel="noopener noreferrer"&gt;Who Owns an IP Address? How to Check with WHOIS and RDAP&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>security</category>
      <category>networking</category>
      <category>bgp</category>
    </item>
    <item>
      <title>Bring Leased IPv4 to AWS with BYOIP (and skip the $0.005/hr charge)</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Fri, 31 Jul 2026 15:38:37 +0000</pubDate>
      <link>https://dev.to/kohanevich/bring-leased-ipv4-to-aws-with-byoip-and-skip-the-0005hr-charge-2a2e</link>
      <guid>https://dev.to/kohanevich/bring-leased-ipv4-to-aws-with-byoip-and-skip-the-0005hr-charge-2a2e</guid>
      <description>&lt;p&gt;Since 1 February 2024, AWS bills $0.005/hour for every public IPv4 address in your account - attached or not. That's ~$3.65/address/month, or ~$934/month for a working /24 (256 addresses). Addresses you bring in via &lt;strong&gt;BYOIP&lt;/strong&gt; are exempt, and Elastic IPs allocated from your own pool are free too.&lt;/p&gt;

&lt;p&gt;The AWS docs cover the happy path but skip the two things that actually cause tickets: &lt;strong&gt;the authorization-context signing step&lt;/strong&gt;, and &lt;strong&gt;whether a leased block even qualifies&lt;/strong&gt;. This post fills both gaps and gives you the full CLI sequence.&lt;/p&gt;

&lt;p&gt;TL;DR: a leased /24 works fine, because AWS validates &lt;em&gt;control&lt;/em&gt; via your RIR, not ownership. You just need the registrant to set up the ROA.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AWS actually checks
&lt;/h2&gt;

&lt;p&gt;When you provision a block, AWS verifies two registry-side records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;ROA&lt;/strong&gt; (Route Origin Authorization) in your RIR's RPKI, authorizing Amazon's ASNs to originate the prefix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDAP records&lt;/strong&gt; proving you control the range, verified either with a signed X.509 authorization context (the classic path) or a DNS TXT record via IPAM (the newer path).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither of these cares who &lt;em&gt;owns&lt;/em&gt; the block in a contractual sense - they care who holds the registration. For a leased /24, that's the IP owner. So the block qualifies as long as the registrant creates the ROA and, if you're using the X.509 path, signs the authorization message for you. A decent leasing provider does this as part of onboarding; if you're wiring it up yourself, budget a back-and-forth with whoever holds the registration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prefix:&lt;/strong&gt; /24 is the most specific IPv4 you can bring. No /25 or longer. (IPv6: /48 for publicly advertised.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RIR:&lt;/strong&gt; ARIN, RIPE, or APNIC, registered to a &lt;strong&gt;business/institutional entity&lt;/strong&gt;, not an individual.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ROA:&lt;/strong&gt; authorize ASNs &lt;strong&gt;16509 and 14618&lt;/strong&gt; (use &lt;strong&gt;8987&lt;/strong&gt; for GovCloud). Set &lt;strong&gt;maxLength to /24&lt;/strong&gt;. Allow up to 24h to propagate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quota:&lt;/strong&gt; 5 ranges per Region; more via a Support ticket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope:&lt;/strong&gt; one block, one Region at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you already advertise the block from your own ASN, create the ROA for &lt;em&gt;your&lt;/em&gt; ASN before adding Amazon's, or you risk disrupting your live announcement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The step everyone trips on: the authorization context
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;provision-byoip-cidr&lt;/code&gt; takes a &lt;code&gt;--cidr-authorization-context&lt;/code&gt; with a &lt;code&gt;Message&lt;/code&gt; and a &lt;code&gt;Signature&lt;/code&gt;. This is where people get stuck, because the docs describe it more than they show it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Message&lt;/code&gt; is a plaintext string in a fixed format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1|aws|&amp;lt;account-id&amp;gt;|&amp;lt;cidr&amp;gt;|&amp;lt;expiry-yyyymmdd&amp;gt;|SHA256|RSAPSS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You sign that message with the &lt;strong&gt;private key of the X.509 certificate&lt;/strong&gt; whose public half is published in your RIR's RDAP record. The base64 of that signature becomes &lt;code&gt;Signature&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# message&lt;/span&gt;
&lt;span class="nv"&gt;text_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1|aws|123456789012|203.0.113.0/24|20261231|SHA256|RSAPSS"&lt;/span&gt;

&lt;span class="c"&gt;# sign with your BYOIP private key&lt;/span&gt;
&lt;span class="nv"&gt;signed_message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$text_message&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | openssl dgst &lt;span class="nt"&gt;-sha256&lt;/span&gt; &lt;span class="nt"&gt;-sigopt&lt;/span&gt; rsa_padding_mode:pss &lt;span class="nt"&gt;-sigopt&lt;/span&gt; rsa_pss_saltlen:-1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-sign&lt;/span&gt; private-key.pem &lt;span class="nt"&gt;-keyform&lt;/span&gt; PEM &lt;span class="se"&gt;\&lt;/span&gt;
  | openssl &lt;span class="nb"&gt;base64&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s1"&gt;'+=/'&lt;/span&gt; &lt;span class="s1"&gt;'-_~'&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things bite here: the signature must use &lt;strong&gt;RSA-PSS&lt;/strong&gt;, and the base64 needs URL-safe substitution (&lt;code&gt;+=/&lt;/code&gt; → &lt;code&gt;-_~&lt;/code&gt;). Get either wrong and provisioning fails validation with an unhelpful message.&lt;/p&gt;

&lt;h2&gt;
  
  
  The provisioning sequence
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Provision the block:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 provision-byoip-cidr &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cidr&lt;/span&gt; 203.0.113.0/24 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cidr-authorization-context&lt;/span&gt; &lt;span class="nv"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$text_message&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,Signature&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$signed_message&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;asynchronous&lt;/strong&gt; - it returns immediately, but the block isn't usable yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Poll until it flips to &lt;code&gt;provisioned&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-byoip-cidrs &lt;span class="nt"&gt;--max-results&lt;/span&gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see &lt;code&gt;State&lt;/code&gt; walk from &lt;code&gt;pending-provision&lt;/code&gt; → &lt;code&gt;provisioned&lt;/code&gt;. If it lands on &lt;code&gt;failed-provision&lt;/code&gt;, the &lt;code&gt;StatusMessage&lt;/code&gt; tells you why - almost always a ROA that hasn't propagated or a maxLength that isn't /24.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Advertise it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 advertise-byoip-cidr &lt;span class="nt"&gt;--cidr&lt;/span&gt; 203.0.113.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State moves to &lt;code&gt;advertised&lt;/code&gt; and AWS starts originating the prefix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Allocate an Elastic IP from your pool&lt;/strong&gt; (free, unlike Amazon-provided EIPs):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 allocate-address &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; eu-central-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--public-ipv4-pool&lt;/span&gt; ipv4pool-ec2-xxxxxxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Associate it&lt;/strong&gt; with an EC2 instance, NAT gateway, or Network Load Balancer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 associate-address &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance-id&lt;/span&gt; i-0abc123 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--allocation-id&lt;/span&gt; eipalloc-0abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. From here your BYOIP addresses behave like any Elastic IP - minus the hourly charge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where BYOIP addresses actually attach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EC2 / VPC via Elastic IP&lt;/strong&gt; - instances, NAT gateways, &lt;strong&gt;NLBs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Global Accelerator&lt;/strong&gt; - assign IPv4 from your own pool directly (IPv4 only).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Amazon SES also has a "BYOIP" feature - it is not this one.&lt;/strong&gt; SES BYOIP is a paid, per-address monthly feature (256-address minimum) for preserving sending reputation. It does &lt;strong&gt;not&lt;/strong&gt; dodge the $0.005/hr charge. Different mechanism, different billing, different purpose. Don't conflate them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timing and gotchas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No SLA on provisioning.&lt;/strong&gt; It's async; allow up to 24h for ROA propagation and a few business days end to end once registry records are set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pending-provision&lt;/code&gt; that won't clear&lt;/strong&gt; = ROA not propagated, or maxLength ≠ /24.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ROA mismatch&lt;/strong&gt; = wrong prefix or missing an ASN. Both 16509 &lt;em&gt;and&lt;/em&gt; 14618 must be authorized, valid for the whole time the block lives in AWS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signature failures&lt;/strong&gt; = not RSA-PSS, or non-URL-safe base64.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quota surprises&lt;/strong&gt; = you get 5 ranges/Region before needing Support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Is it worth it?
&lt;/h2&gt;

&lt;p&gt;For a few addresses with no existing block: no - just use Amazon's and move on. For dozens of addresses, or anywhere IP reputation and migration continuity matter: absolutely. A working /24 is ~$934/month on Amazon-provided addresses versus $0 in AWS address charges on BYOIP. Your only cost is the lease, which runs a fraction of that - and nothing at all if you own the block.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Full version with the cost breakdown, the leased-IPv4 details, and the complete requirements is on our blog: &lt;a href="https://ipbnb.com/blog/aws-byoip-leased-ipv4" rel="noopener noreferrer"&gt;How to Bring Leased IPv4 to AWS&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>Importing a leased /24 into OVHcloud with BYOIP (and skipping the $612/mo IP bill)</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Thu, 30 Jul 2026 10:04:58 +0000</pubDate>
      <link>https://dev.to/kohanevich/importing-a-leased-24-into-ovhcloud-with-byoip-and-skipping-the-612mo-ip-bill-6il</link>
      <guid>https://dev.to/kohanevich/importing-a-leased-24-into-ovhcloud-with-byoip-and-skipping-the-612mo-ip-bill-6il</guid>
      <description>&lt;p&gt;I run IPbnb, so IPv4 economics are kind of my whole day. But this one still catches teams off guard, so let me walk through it like an engineer, not a marketer.&lt;/p&gt;

&lt;p&gt;OVHcloud bills Additional IPs at &lt;strong&gt;$2.39 per IP per month&lt;/strong&gt;. Fine for a couple of addresses. Now do a &lt;code&gt;/24&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;256 addresses × $2.39 = ~$612 / month, forever
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you own none of it. The addresses are OVH's, the reputation you build on them can't leave with you, and the meter never stops. There's a cleaner way, and it's called BYOIP.&lt;/p&gt;

&lt;h2&gt;
  
  
  What BYOIP actually does
&lt;/h2&gt;

&lt;p&gt;Bring Your Own IP means OVHcloud announces a block &lt;strong&gt;you&lt;/strong&gt; control instead of renting you theirs. No per-IP rental on imported space - OVH advertises it for free. So the only real question is where the block comes from: rent, buy, or lease.&lt;/p&gt;

&lt;p&gt;You don't need to own a &lt;code&gt;/24&lt;/code&gt; to do this. Lease a clean one (we do this at IPbnb from ~$79/mo), import it via BYOIP, and you're paying roughly &lt;strong&gt;85% less&lt;/strong&gt; than renting OVH's 256 addresses - with a block whose reputation is yours and portable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements (the short list)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RIR:&lt;/strong&gt; ARIN, RIPE, or APNIC. NIRs are experimental; AFRINIC/LACNIC not supported yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size:&lt;/strong&gt; &lt;code&gt;/24&lt;/code&gt; minimum, &lt;code&gt;/19&lt;/code&gt; max. It's delivered to you as one or more &lt;code&gt;/24&lt;/code&gt; blocks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean + unannounced:&lt;/strong&gt; don't have it advertised elsewhere when it goes live, or you'll get routing conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WHOIS status&lt;/strong&gt; must be a real allocation/assignment (e.g. RIPE &lt;code&gt;ALLOCATED PA&lt;/code&gt; / &lt;code&gt;ASSIGNED PA&lt;/code&gt;), matching the exact prefix.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Publish a route object&lt;/strong&gt; at your RIR with OVH's ASN as origin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;route&lt;/span&gt;:    &lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;/&lt;span class="m"&gt;24&lt;/span&gt;
&lt;span class="n"&gt;origin&lt;/span&gt;:   &lt;span class="n"&gt;AS16276&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt;:   &lt;span class="n"&gt;RIPE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Prove control&lt;/strong&gt; by dropping the token OVH gives you into the &lt;code&gt;descr&lt;/code&gt; field of the &lt;code&gt;inetnum&lt;/code&gt; (its own line):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;inetnum&lt;/span&gt;:  &lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt; - &lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;255&lt;/span&gt;
&lt;span class="n"&gt;descr&lt;/span&gt;:    -----&lt;span class="n"&gt;BEGIN&lt;/span&gt; &lt;span class="n"&gt;TOKEN&lt;/span&gt;-----
&lt;span class="n"&gt;descr&lt;/span&gt;:    &amp;lt;&lt;span class="n"&gt;your&lt;/span&gt;-&lt;span class="n"&gt;ovh&lt;/span&gt;-&lt;span class="n"&gt;token&lt;/span&gt;&amp;gt;
&lt;span class="n"&gt;descr&lt;/span&gt;:    -----&lt;span class="n"&gt;END&lt;/span&gt; &lt;span class="n"&gt;TOKEN&lt;/span&gt;-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Order it&lt;/strong&gt; in the Control Panel: &lt;code&gt;Network &amp;gt; IP &amp;gt; + Bring Your Own IP&lt;/code&gt;. Pick the RIR, the region, the range, and OVH's AS (or your own via BYOAS). Delivery takes a few weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Go live&lt;/strong&gt; by assigning a &lt;code&gt;/24&lt;/code&gt; to an eligible service. Announcement is assignment-driven - nothing is advertised until you attach the block to a Bare Metal box, Public Cloud instance, or a vRack-connected service.&lt;/p&gt;

&lt;p&gt;Need smaller blocks? Slice via the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/ip/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;/bringYourOwnIp/slice&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"slicingSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;splits&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="err"&gt;s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gotchas worth knowing before you commit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Region lock-in is gone.&lt;/strong&gt; OVH dropped the old ARIN→US / RIPE→EU rule. A RIPE block now works in any OVH region. You still choose one region per import, and you can't move a range across regions without releasing and re-ordering it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No WHOIS edits from the panel.&lt;/strong&gt; OVH doesn't own the block, so reverse DNS runs through delegated ARPA zones instead. PTRs work; WHOIS stays with the holder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kill the old announcement fast.&lt;/strong&gt; If the block was advertised elsewhere, withdraw that the moment OVH delivery completes, or you're multihoming into packet loss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anti-DDoS is included&lt;/strong&gt; on BYOIP ranges at no extra cost, which is a nice freebie.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The leased-block angle
&lt;/h2&gt;

&lt;p&gt;BYOIP isn't owner-only. OVH just needs proof you're authorised to route the prefix. With a leased block, that's a Letter of Authorisation from the holder plus correct route/ROA objects - which, if your provider actually supports BYOIP, is already done for you before you place the order. That's the difference between leasing from someone who preps the block and someone who just emails you a range.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If you need address space for years, buy it. For hosting, SaaS, and migrations, paying ~$612/mo to rent IPs you'll never own is hard to justify when ~$79 gets you the same &lt;code&gt;/24&lt;/code&gt; with your reputation intact.&lt;/p&gt;

&lt;p&gt;Full step-by-step, requirements, and the honest cost math here:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://ipbnb.com/blog/ovh-byoip-leased-ipv4" rel="noopener noreferrer"&gt;Bring a Leased /24 to OVHcloud: BYOIP Guide →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>Whose ASN Goes on Your Leased IPv4 Prefix?</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Mon, 20 Jul 2026 08:22:21 +0000</pubDate>
      <link>https://dev.to/kohanevich/whose-asn-goes-on-your-leased-ipv4-prefix-1l0h</link>
      <guid>https://dev.to/kohanevich/whose-asn-goes-on-your-leased-ipv4-prefix-1l0h</guid>
      <description>&lt;p&gt;You leased a /24. Something has to originate it in BGP. That something has an ASN attached, and if the wrong ASN is attached, your prefix gets dropped by every network running Route Origin Validation.&lt;/p&gt;

&lt;p&gt;That is the entire problem. Here is how the four options differ at the object level.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four origination paths
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Origin AS&lt;/th&gt;
&lt;th&gt;Who creates what&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Your own ASN + BGP&lt;/td&gt;
&lt;td&gt;Yours&lt;/td&gt;
&lt;td&gt;Owner issues LOA + &lt;code&gt;route:&lt;/code&gt; + ROA, all naming your ASN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upstream/host announces&lt;/td&gt;
&lt;td&gt;Provider's&lt;/td&gt;
&lt;td&gt;Same three objects, naming &lt;strong&gt;their&lt;/strong&gt; ASN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud BYOIP&lt;/td&gt;
&lt;td&gt;Cloud's, or yours on AWS&lt;/td&gt;
&lt;td&gt;ROA naming cloud ASN (or yours via BYOASN) + RDAP proof&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Third-party AS&lt;/td&gt;
&lt;td&gt;Partner's&lt;/td&gt;
&lt;td&gt;Same three objects, naming the partner's ASN&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three of the four need no ASN registered to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ROA.asID&lt;/code&gt; must equal the origin AS in the announcement. RFC 6811 gives three outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NotFound&lt;/strong&gt; - no covering ROA. Still widely accepted, decreasingly so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valid&lt;/strong&gt; - origin AS and prefix length both match.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invalid&lt;/strong&gt; - wrong origin AS, or announced prefix longer than &lt;code&gt;maxLength&lt;/code&gt;. Dropped by every validating peer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Invalid is the dangerous one because it fails partially. Peers doing ROV drop you, peers that do not still carry you, and the symptom looks like an application bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  The failure I see most
&lt;/h3&gt;

&lt;p&gt;Renter plans to get their own ASN later. Asks the IP owner to create the ROA against that future ASN now. Goes live with the host announcing from the host's AS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROA:          198.51.100.0/24  origin AS64496  maxLength 24
Announcement: 198.51.100.0/24  AS_PATH ... 64511
                                            ^^^^^ mismatch -&amp;gt; Invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sequence it the other way. Decide the origin, then create the ROA.&lt;/p&gt;

&lt;h3&gt;
  
  
  Also watch maxLength
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROA:          203.0.113.0/22   origin AS64496  maxLength 22
Announcement: 203.0.113.0/24   origin AS64496
                        ^^^ correct AS, too specific -&amp;gt; Invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Correct ASN is not sufficient. &lt;code&gt;maxLength&lt;/code&gt; has to cover what you actually originate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying before you announce
&lt;/h2&gt;

&lt;p&gt;RIPEstat works regardless of which RIR administers the block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://stat.ripe.net/data/rpki-validation/data.json?resource=64496&amp;amp;prefix=198.51.100.0/24"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.data.status, .data.validating_roas'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anything other than &lt;code&gt;"valid"&lt;/code&gt; means stop. For a local relying-party cache, use Routinator, rpki-client or FORT.&lt;/p&gt;

&lt;p&gt;Note: the RIPE NCC RPKI Validator has been unmaintained since 1 July 2021 and the public instance was migrated to Routinator in September 2021. Plenty of tutorials still point at it.&lt;/p&gt;

&lt;p&gt;Then confirm what the world actually sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;whois &lt;span class="nt"&gt;-h&lt;/span&gt; whois.radb.net &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s1"&gt;'-i origin AS64496'&lt;/span&gt;   &lt;span class="c"&gt;# route objects&lt;/span&gt;
&lt;span class="c"&gt;# plus RIPE RIS / BGPView / HE looking glass for the live AS_PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cloud specifics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AWS commercial regions.&lt;/strong&gt; ROA must authorise &lt;code&gt;16509&lt;/code&gt; and &lt;code&gt;14618&lt;/code&gt;, &lt;code&gt;maxLength 24&lt;/code&gt; for IPv4. GovCloud (US) uses &lt;code&gt;8987&lt;/code&gt;. Authorisation is two-part: the ROA plus a self-signed X.509 certificate published in the RDAP remarks for the prefix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS BYOASN.&lt;/strong&gt; You are not forced onto Amazon's origin AS. Bring an ASN you hold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 provision-ipam-byoasn &lt;span class="nt"&gt;--ipam-id&lt;/span&gt; ipam-xxxx &lt;span class="nt"&gt;--asn&lt;/span&gt; 64496 &lt;span class="nt"&gt;--asn-authorization-context&lt;/span&gt; ...
aws ec2 associate-ipam-byoasn &lt;span class="nt"&gt;--asn&lt;/span&gt; 64496 &lt;span class="nt"&gt;--cidr&lt;/span&gt; 198.51.100.0/24
aws ec2 advertise-byoip-cidr &lt;span class="nt"&gt;--cidr&lt;/span&gt; 198.51.100.0/24 &lt;span class="nt"&gt;--asn&lt;/span&gt; 64496
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ROA then names your ASN, not Amazon's.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Azure Custom IP Prefix.&lt;/strong&gt; Origin AS must be &lt;code&gt;8075&lt;/code&gt; (public) or &lt;code&gt;8070&lt;/code&gt; (US Gov). Parent IPv4 prefix must be /21 to /24. Two constraints that kill use cases outright: SMTP is not permitted from Azure BYOIP space, and you must decommission the range &lt;em&gt;before&lt;/em&gt; modifying or deleting the ROA - otherwise Microsoft keeps advertising a prefix it is no longer authorised to originate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you actually want your own ASN?
&lt;/h2&gt;

&lt;p&gt;RIPE still requires multihoming. ripe-679 §2.0 is unambiguous, and proposal 2025-01 - which would have dropped all justification for a first ASN - was &lt;strong&gt;withdrawn on 6 July 2026&lt;/strong&gt;. The old criteria stand.&lt;/p&gt;

&lt;p&gt;You submit a routing policy in RPSL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aut-num:  AS64496
import:   from AS64500 accept ANY
import:   from AS64501 accept ANY
export:   to AS64500 announce AS64496
export:   to AS64501 announce AS64496
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two upstreams in that object is not decoration. RIPE NCC may contact both to verify.&lt;/p&gt;

&lt;p&gt;Single-homed with one /24? An ASN gets you EUR 50 per assignment, registry obligations, and a routing policy identical to your upstream's. Skip it until you are genuinely multihoming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-flight
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] LOA names the &lt;strong&gt;announcing&lt;/strong&gt; ASN&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;route:&lt;/code&gt; object exists with correct &lt;code&gt;origin:&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] ROA correct on both &lt;code&gt;asID&lt;/code&gt; and &lt;code&gt;maxLength&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] RPKI status &lt;code&gt;valid&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Prefix visible from multiple vantage points, observed origin matches the ROA&lt;/li&gt;
&lt;li&gt;[ ] rDNS delegated&lt;/li&gt;
&lt;li&gt;[ ] Reputation checked on the block &lt;em&gt;and&lt;/em&gt; the announcing ASN&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Longer version with the full path-by-path breakdown, the RIPE policy history, and the LOA/IRR/ROA sequencing: &lt;a href="https://ipbnb.com/blog/asn-to-announce-ipv4" rel="noopener noreferrer"&gt;https://ipbnb.com/blog/asn-to-announce-ipv4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>bgp</category>
      <category>devops</category>
      <category>aws</category>
    </item>
    <item>
      <title>IP Transit: What Actually Happens Before Your Network Reaches the Internet</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Wed, 08 Jul 2026 13:48:43 +0000</pubDate>
      <link>https://dev.to/kohanevich/ip-transit-what-actually-happens-before-your-network-reaches-the-internet-46dg</link>
      <guid>https://dev.to/kohanevich/ip-transit-what-actually-happens-before-your-network-reaches-the-internet-46dg</guid>
      <description>&lt;p&gt;You can have racks, routers, servers, switches, and clean configs — but none of that makes your network reachable from the public internet by default.&lt;/p&gt;

&lt;p&gt;For that, you need &lt;strong&gt;IP transit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;IP transit is the service that connects your autonomous system to the rest of the internet. Your upstream provider carries your traffic to other networks and announces your prefixes so return traffic knows how to find you.&lt;/p&gt;

&lt;p&gt;In other words: transit is what turns your network from an isolated island into part of the global routing system.&lt;/p&gt;

&lt;h2&gt;
  
  
  How IP Transit Works
&lt;/h2&gt;

&lt;p&gt;At the technical level, IP transit usually looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your router connects to the transit provider’s router.&lt;/li&gt;
&lt;li&gt;You establish a BGP session.&lt;/li&gt;
&lt;li&gt;The provider sends you routes, often the full internet routing table.&lt;/li&gt;
&lt;li&gt;You announce your own prefixes.&lt;/li&gt;
&lt;li&gt;The provider propagates those announcements to its peers and upstreams.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last step matters a lot. Sending traffic out is only half the job. If your prefixes are not announced correctly, the rest of the internet will not know how to send traffic back.&lt;/p&gt;

&lt;p&gt;For IPv4, the practical minimum is usually a &lt;strong&gt;/24&lt;/strong&gt;, because smaller prefixes are commonly filtered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transit vs Peering
&lt;/h2&gt;

&lt;p&gt;Transit and peering are related, but they solve different problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IP transit&lt;/strong&gt; gives you reachability to the whole internet. You pay a provider, usually per Mbps, and they carry your traffic globally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Peering&lt;/strong&gt; lets you exchange traffic directly with another network, often through an internet exchange. It is great for cost and latency when you have enough traffic with specific networks, but it does not replace transit for most operators.&lt;/p&gt;

&lt;p&gt;The common path is simple:&lt;/p&gt;

&lt;p&gt;Start with transit. Add peering later when traffic volume makes it worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Need Before Buying Transit
&lt;/h2&gt;

&lt;p&gt;Before a transit provider can bring you online, you typically need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;ASN&lt;/strong&gt; to identify your network in BGP&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;BGP-capable router&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;An upstream/transit agreement&lt;/li&gt;
&lt;li&gt;IPv4 and/or IPv6 address space you are allowed to announce&lt;/li&gt;
&lt;li&gt;Correct routing objects and, ideally, RPKI ROAs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first three are usually straightforward.&lt;/p&gt;

&lt;p&gt;IPv4 is where things often slow down.&lt;/p&gt;

&lt;h2&gt;
  
  
  The IPv4 Problem
&lt;/h2&gt;

&lt;p&gt;IPv6 is available. IPv4 is not.&lt;/p&gt;

&lt;p&gt;In the RIPE region, the free IPv4 pool has been exhausted for years. If you need IPv4 today, your main options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait for allocation&lt;/li&gt;
&lt;li&gt;Buy space on the transfer market&lt;/li&gt;
&lt;li&gt;Lease IPv4 blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each option has trade-offs.&lt;/p&gt;

&lt;p&gt;Waiting can take a long time. Buying requires upfront capital. Leasing gives operators a faster way to get announceable address space without locking themselves into a large purchase.&lt;/p&gt;

&lt;p&gt;For hosting providers, ISPs, CDNs, and infrastructure teams, this can be the difference between launching now and waiting months.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing Is Not Just “$/Mbps”
&lt;/h2&gt;

&lt;p&gt;IP transit pricing is usually quoted per Mbps per month, but the number depends on context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commit size&lt;/li&gt;
&lt;li&gt;Location&lt;/li&gt;
&lt;li&gt;Provider tier&lt;/li&gt;
&lt;li&gt;Billing model&lt;/li&gt;
&lt;li&gt;SLA&lt;/li&gt;
&lt;li&gt;DDoS protection&lt;/li&gt;
&lt;li&gt;Route quality&lt;/li&gt;
&lt;li&gt;Redundancy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A low price in a major hub at 100 Gbps does not mean the same price exists for a small commit in a less connected market.&lt;/p&gt;

&lt;p&gt;Also, cheaper transit is not always better transit. Bad routes, weak support, or poor visibility can cost more than the savings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Takeaway
&lt;/h2&gt;

&lt;p&gt;IP transit is the foundation of public internet reachability.&lt;/p&gt;

&lt;p&gt;To bring a network online, you need more than bandwidth. You need BGP, an ASN, upstream connectivity, route propagation, and address space that the global internet will accept.&lt;/p&gt;

&lt;p&gt;And in many real deployments, IPv4 becomes the bottleneck — not the router, not the contract, and not the cross-connect.&lt;/p&gt;

&lt;p&gt;So plan for IPv4 early. If your network depends on it, your rollout timeline probably does too.&lt;/p&gt;

&lt;p&gt;Full version: &lt;a href="https://ipbnb.com/blog/what-is-ip-transit" rel="noopener noreferrer"&gt;What Is IP Transit?&lt;/a&gt;&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>devops</category>
      <category>network</category>
    </item>
    <item>
      <title>IPv8: A Beautiful Spec With a Threat Model Problem</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Tue, 30 Jun 2026 13:26:20 +0000</pubDate>
      <link>https://dev.to/kohanevich/ipv8-a-beautiful-spec-with-a-threat-model-problem-2gp9</link>
      <guid>https://dev.to/kohanevich/ipv8-a-beautiful-spec-with-a-threat-model-problem-2gp9</guid>
      <description>&lt;p&gt;I work in the IPv4 address market, which means a new addressing proposal hits my inbox the moment it goes public. Most are noise. &lt;code&gt;draft-thain-ipv8&lt;/code&gt;, submitted to the IETF in April 2026, is more interesting than most - not because it'll ship (it won't), but because its architecture is a clean case study in how a well-intentioned spec can accidentally specify a surveillance platform. Let's read it like engineers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The naming collision (skip if you already know)
&lt;/h2&gt;

&lt;p&gt;Three unrelated things share the name "IPv8":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;py-ipv8&lt;/strong&gt; - a working P2P overlay from TU Delft over UDP, using Curve25519/Ed25519 identities. Nothing to do with TCP/IP replacement. The name is a joke about IPv6 adoption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PIP (historical IPv8)&lt;/strong&gt; - Paul Francis, 1992, RFC 1621/1622. Lost the IPng race to SIPP because variable-length addresses were murder in hardware. Historic since 2016.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;draft-thain-ipv8&lt;/strong&gt; - the 2026 individual submission everyone is arguing about. This post is only about that one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The addressing model
&lt;/h2&gt;

&lt;p&gt;IPv8 defines a 64-bit address laid out as &lt;code&gt;r.r.r.r.n.n.n.n&lt;/code&gt; - eight octets:&lt;/p&gt;

&lt;p&gt;+-------------------+-------------------+&lt;/p&gt;

&lt;p&gt;|   ASN (32 bits)   |  Host (32 bits)   |&lt;/p&gt;

&lt;p&gt;+-------------------+-------------------+&lt;/p&gt;

&lt;p&gt;r.r.r.r           n.n.n.n&lt;/p&gt;

&lt;p&gt;The high 32 bits carry an ASN; the low 32 bits are a host address with IPv4 semantics. The backward-compatibility hook is the part worth pausing on:&lt;/p&gt;

&lt;p&gt;if (asn_prefix == 0.0.0.0) {&lt;/p&gt;

&lt;p&gt;// treat as legacy IPv4, standard rules apply&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;0.0.0.0.a.b.c.d&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; IPv4. Clean idea on paper.&lt;/p&gt;

&lt;p&gt;The consequences are large:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each ASN holder gets &lt;code&gt;2^32&lt;/code&gt; host addresses (~4.3 billion). Exhaustion stops being a meaningful constraint at any org scale.&lt;/li&gt;
&lt;li&gt;The global routing table - currently 900k+ prefixes with no structural ceiling - gets capped near one entry per ASN (~175k today), because deaggregation below /16 is forbidden. That's the architecturally bounded BGP table people have wanted for years.&lt;/li&gt;
&lt;li&gt;Header cost: +8 bytes vs IPv4 (source and destination each grow 32 → 64 bits). TTL, Protocol, Flags, Checksum are unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the genuinely attractive half of the draft. If you've ever stared at the routing table growth curve and winced, the bounding mechanism is hard not to like.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zone Server
&lt;/h2&gt;

&lt;p&gt;Here's where it stops being an addressing proposal and becomes a platform. IPv8 mandates a per-segment &lt;strong&gt;Zone Server&lt;/strong&gt;, active/active, that consolidates basically everything:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DHCP8&lt;/td&gt;
&lt;td&gt;Address assignment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS8&lt;/td&gt;
&lt;td&gt;Resolution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTP8&lt;/td&gt;
&lt;td&gt;Time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth8&lt;/td&gt;
&lt;td&gt;Authentication (OAuth2 + JWT)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WHOIS8&lt;/td&gt;
&lt;td&gt;Route validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ACL8&lt;/td&gt;
&lt;td&gt;Access control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NetLog8&lt;/td&gt;
&lt;td&gt;Telemetry / logging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XLATE8&lt;/td&gt;
&lt;td&gt;IPv4 ↔ IPv8 translation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A device joins, fires one DHCP8 request, and gets every service endpoint in a single reply. Auth is JWT validated locally, no round trip to an external IdP. From an ops perspective, the "one box, one request" story is genuinely elegant.&lt;/p&gt;

&lt;p&gt;Routing decisions run on a 32-bit &lt;strong&gt;Cost Factor&lt;/strong&gt;, accumulated from seven inputs: RTT, packet loss, congestion window state, session stability, link capacity, economic policy, and great-circle distance as a speed-of-light floor. That last one is sharp - any path claiming to beat the physics floor is flagged as anomalous by definition. I like it as a design instinct.&lt;/p&gt;

&lt;p&gt;Transition avoids a flag day via &lt;code&gt;8to4&lt;/code&gt; tunnelling encapsulated over HTTPS, so it slips through firewalls without per-box config.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it breaks (the ordinary objections)
&lt;/h2&gt;

&lt;p&gt;The community pushback is fair and mostly consistent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No process.&lt;/strong&gt; IPv6 came out of a multi-year working-group bake-off (CATNIP, TUBA, SIPP). This is a solo I-D with no WG, no sponsor, and a datatracker page that says outright it isn't endorsed. It expires Oct 19, 2026 absent adoption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layering violation.&lt;/strong&gt; OAuth2/JWT is Layer 7 logic shoved into Layer 3. Access switches, industrial controllers, and basic routers aren't built to do application-level authz at line rate. I'm softer on this than most - hardware refreshes on 7-10 year cycles regardless, and ISPs ship ~180M CPE units a year - but "the silicon could eventually do it" is not the same as "the ecosystem will require it."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Version field.&lt;/strong&gt; Every ASIC checks the IP Version field and drops anything that isn't 4 or 6. A Version 8 packet dies at hop one. XLATE8 is the answer - legacy devices behind an IPv8 gateway emit plain IPv4 and never send a Version 8 packet - but the whole transition story rests on XLATE8 being as transparent in production as the spec claims, and nobody has tested that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provenance.&lt;/strong&gt; GPTZero reportedly flagged ~76% of the text as likely AI-generated. The author acknowledges AI assistance. The concern isn't the tool; it's whether the design reflects lived operational experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timing.&lt;/strong&gt; Two weeks before the draft argued IPv6 had failed, Google's IPv6 traffic crossed 50% for the first time. The premise aged badly in real time.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The part the technical critique mostly misses
&lt;/h2&gt;

&lt;p&gt;All of the above is solvable in principle. The thing that isn't solvable by iteration is what the Zone Server &lt;em&gt;becomes&lt;/em&gt; once you treat it as a threat model instead of a feature list.&lt;/p&gt;

&lt;p&gt;Walk the mechanisms as an adversary would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DNS8 is not swappable.&lt;/strong&gt; Today, DNS censorship is the weakest control - flip your resolver to &lt;code&gt;1.1.1.1&lt;/code&gt; and you're out. Under IPv8, resolution lives in the mandatory egress box. There is no "use another resolver." Unresolved destination → dropped locally, before the packet ever leaves your segment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WHOIS8 is a registry-level kill switch.&lt;/strong&gt; Every destination ASN must be present and valid in WHOIS8 or the packet is dropped, and unvalidated routes are never installed at the BGP8 level at all. So censorship stops requiring DPI or border filtering - pressure the registry, remove the record, and the target is unreachable at the protocol layer everywhere IPv8 runs. No record, no route, no reachability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth2/JWT ends anonymous connections by design.&lt;/strong&gt; Every managed device authenticates before its first packet. The stated goal is killing malware C2 - legitimate. The side effect is that the anonymity Tor and VPNs rely on stops existing at the IP layer, and whoever holds the identity infrastructure can attribute every connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NetLog8 makes logging mandatory.&lt;/strong&gt; Real-time telemetry at every Zone Server - every auth, connection, and policy hit, timestamped. "Observability for operators" and "comprehensive surveillance record for a state actor" are the same dataset.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the spec is silent exactly where it shouldn't be: no governance model for who runs the Zone Server, no oversight on WHOIS8 record removal, no judicial-review path for ACL8 rules or JWT revocation. The entire thing assumes good-faith operators. That assumption does not survive contact with a meaningful chunk of the world's governments.&lt;/p&gt;

&lt;p&gt;We've seen this shape before. Huawei's 2020 "New IP" pitch to the ITU-T proposed per-packet, authenticated, government-controllable filtering at the network layer and was rejected by the IETF, ISOC, and several governments precisely because it baked control into the protocol. IPv8 reaches a structurally identical endpoint through different mechanisms - apparently without the author intending it. Intent doesn't edit the architecture.&lt;/p&gt;

&lt;p&gt;The clean way to put it: today a national firewall is expensive overlay infrastructure fighting a protocol built for openness. IPv8 inverts the relationship. The authenticated, logged, gateway-validated network becomes the base layer, and the open internet becomes the overlay you have to fight to reach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why an IPv4 trader cares
&lt;/h2&gt;

&lt;p&gt;Short term: nothing. The draft expires without WG adoption, no vendor or RIR backs it, and IPv4 leasing is unaffected.&lt;/p&gt;

&lt;p&gt;Longer term, two things are worth watching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The addressing logic.&lt;/strong&gt; If a future, better-sponsored proposal inherits the "each ASN holder gets a giant block" model while keeping IPv4 backward compatibility, it attacks both pillars the secondary IPv4 market rests on - scarcity and IPv6 transition cost - simultaneously. That's speculative and distant, but it's the scenario to model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The control pattern.&lt;/strong&gt; Consolidating resolution, identity, route validation, and logging into one mandatory platform will resurface in proposals that &lt;em&gt;do&lt;/em&gt; have momentum. When it does, the only question that matters is who controls the platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;draft-thain-ipv8&lt;/code&gt; is not going to standardize. But it's a useful artifact: it proves you can bound the BGP table and unify network management at the protocol layer - and it proves that the same consolidation, done without a governance model, hands you a censorship substrate for free. The address format being elegant doesn't change that. The end-to-end principle is the thing keeping those two outcomes separable, and it's worth defending precisely when the alternative looks this tidy.&lt;/p&gt;

&lt;p&gt;Full technical write-up with the rest of the spec breakdown is here: &lt;a href="https://ipbnb.com/blog/ipv8-internet-protocol" rel="noopener noreferrer"&gt;https://ipbnb.com/blog/ipv8-internet-protocol&lt;/a&gt;&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>security</category>
      <category>networking</category>
    </item>
    <item>
      <title>Don't Let Your IPAM Drift: Managing Leased IPv4 the API-First Way</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Wed, 17 Jun 2026 04:04:11 +0000</pubDate>
      <link>https://dev.to/kohanevich/dont-let-your-ipam-drift-managing-leased-ipv4-the-api-first-way-1pmo</link>
      <guid>https://dev.to/kohanevich/dont-let-your-ipam-drift-managing-leased-ipv4-the-api-first-way-1pmo</guid>
      <description>&lt;p&gt;Almost every IPAM mess I've debugged traces back to one root cause: the record and the reality drifted apart. Someone assigned an address and forgot to log it. A block expired and nothing flagged it. The spreadsheet said one thing, the routers said another.&lt;/p&gt;

&lt;p&gt;With owned IPv4 you can usually recover from that. With leased IPv4 you have less room, because a leased block carries three things owned space doesn't: an expiry date, a reputation you inherited, and an owner who isn't you. You either manage those as data, or they end up managing you.&lt;/p&gt;

&lt;p&gt;Here's how I'd wire it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the data model
&lt;/h2&gt;

&lt;p&gt;Before reaching for any tool, decide what a leased block actually &lt;em&gt;is&lt;/em&gt; in your system. At minimum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;203.0.113.0/24&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;active&lt;/span&gt;
&lt;span class="na"&gt;lease&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ACME-LIR&lt;/span&gt;
  &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-06-01&lt;/span&gt;
  &lt;span class="na"&gt;expiry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2027-06-01&lt;/span&gt;
  &lt;span class="na"&gt;loa_reference&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LOA-2026-0481&lt;/span&gt;
&lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;origin_asn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;64500&lt;/span&gt;
  &lt;span class="na"&gt;roa_status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;valid&lt;/span&gt;          &lt;span class="c1"&gt;# valid | invalid | unknown&lt;/span&gt;
  &lt;span class="na"&gt;irr_registered&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;reputation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;clean&lt;/span&gt;              &lt;span class="c1"&gt;# clean | listed | watch&lt;/span&gt;
  &lt;span class="na"&gt;last_checked&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-06-15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three fields that make leased space different - &lt;code&gt;lease.expiry&lt;/code&gt;, &lt;code&gt;lease.owner&lt;/code&gt;, and &lt;code&gt;reputation.status&lt;/code&gt; - are exactly the ones a generic IPAM setup tends to leave out. Don't leave them out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model it in NetBox, and let the API do the writing
&lt;/h2&gt;

&lt;p&gt;NetBox is the tool I reach for here: open-source, IPAM plus DCIM, and an API that covers everything the UI does. Define the lease fields once as custom fields (&lt;code&gt;lease_owner&lt;/code&gt;, &lt;code&gt;lease_expiry&lt;/code&gt;, &lt;code&gt;loa_reference&lt;/code&gt;, &lt;code&gt;roa_status&lt;/code&gt;, &lt;code&gt;reputation&lt;/code&gt;), then register a freshly leased block in a single call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pynetbox&lt;/span&gt;

&lt;span class="n"&gt;nb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pynetbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://netbox.internal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;token&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prefix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;203.0.113.0/24&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Leased /24 - web tier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;custom_fields&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lease_owner&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ACME-LIR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lease_expiry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2027-06-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;loa_reference&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LOA-2026-0481&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;roa_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;valid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reputation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;clean&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the lease metadata lives next to the prefix, not in a contract PDF nobody opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Allocate addresses through the API, not by hand
&lt;/h2&gt;

&lt;p&gt;Manual assignment is the single biggest source of drift. Close that gap by allocating from NetBox's next-available-IP endpoint, so the assignment and the record are the same operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;203.0.113.0/24&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;available_ips&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dns_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web-01.customer.example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# -&amp;gt; 203.0.113.5/24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no window where inventory and reality disagree, because writing the record &lt;em&gt;is&lt;/em&gt; the allocation. Wire this into your provisioning flow and the "who's on this address?" problem stops existing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify routing before you announce, and know who owns the ROA
&lt;/h2&gt;

&lt;p&gt;This is the leased-space gotcha that trips up strong teams: you cannot create your own ROA for leased space. Only the resource holder - the block owner, or the platform you leased from - can create the Route Origin Authorization, update the IRR route objects, and issue the LOA. Your job is to &lt;em&gt;confirm&lt;/em&gt; it's all in place and that your origin validates before you announce a single route.&lt;/p&gt;

&lt;p&gt;A quick scripted check against RIPEstat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://stat.ripe.net/data/rpki-validation/data.json?resource=AS64500&amp;amp;prefix=203.0.113.0/24"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.data.status'&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; valid&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that returns &lt;code&gt;invalid&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;, stop and fix it with the owner before the prefix goes live - otherwise every network running ROV will drop your routes. Fold the result straight back into &lt;code&gt;routing.roa_status&lt;/code&gt; so your inventory reflects what the routing table actually believes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat reputation as a scheduled job
&lt;/h2&gt;

&lt;p&gt;You inherit a block's history, so check it before assignment and keep checking on a timer. The DNSBL mechanism is simple enough to script and stay list-agnostic - point &lt;code&gt;$DNSBL_ZONE&lt;/code&gt; at whichever current lists you trust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;check_dnsbl&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;reversed
  &lt;span class="nv"&gt;reversed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'{print $4"."$3"."$2"."$1}'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;dig +short &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;reversed&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;zone&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s1"&gt;'^127\.'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"LISTED &lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$zone&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
  &lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"clean  &lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="nv"&gt;$zone&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

check_dnsbl 203.0.113.5 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DNSBL_ZONE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it across the block on a schedule, write the result and timestamp back into &lt;code&gt;reputation.status&lt;/code&gt; / &lt;code&gt;last_checked&lt;/code&gt;, and alert on any change. Keep mail-sending IPs on separate, warmed space so one customer's mistake doesn't taint a block shared with everyone else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Catch renewals before they catch you
&lt;/h2&gt;

&lt;p&gt;The authorizations that let you announce - the LOA and the ROA - are tied to the lease term. Let a lease lapse and you don't lose paperwork, you lose routing. So query for blocks nearing expiry on a cron and push them somewhere a human will actually look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pynetbox&lt;/span&gt;

&lt;span class="n"&gt;nb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pynetbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://netbox.internal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;token&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;horizon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;nb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;expiry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;custom_fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lease_expiry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expiry&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;horizon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Renewal due: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;custom_fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lease_owner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pipe that into Slack or your ticketing system and renewals become a planned task instead of a 2 a.m. incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which tool?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;phpIPAM&lt;/strong&gt; - free, light, supports custom fields, fine for smaller footprints you're happy to self-host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NetBox&lt;/strong&gt; - open-source, API-first, the one I'd build automation on (everything above assumes it).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SolarWinds IPAM&lt;/strong&gt; - mid-market, with discovery and conflict detection if you want the tool to reconcile itself against the network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infoblox&lt;/strong&gt; - enterprise DDI, integrated DNS/DHCP/IPAM, priced for scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whatever you pick, the test is the same: can it store lease owner, expiry, and reputation, and can you write to it from code? If yes, you can keep records and reality in lockstep. If no, you'll be back to debugging drift.&lt;/p&gt;

&lt;p&gt;That's the whole philosophy - model the lease as data, let the API do the writing, and put reputation and renewals on a timer. The unglamorous automation is exactly what lets you scale leased IPv4 without surprises.&lt;/p&gt;

&lt;p&gt;If you want the longer, less code-heavy treatment - the full lease-to-deployment workflow, a setup checklist for new blocks, and a deeper tool comparison - I wrote it up here: &lt;strong&gt;&lt;a href="https://ipbnb.com/blog/ipam-leased-ipv4-best-practices" rel="noopener noreferrer"&gt;IP Address Management for Leased IPv4: Best Practices for Hosting Providers&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>infrastructure</category>
      <category>automation</category>
      <category>networking</category>
    </item>
    <item>
      <title>Is Your IPv4 Block Blacklisted? Checking a /24 the DNSBL Way</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Thu, 11 Jun 2026 10:22:14 +0000</pubDate>
      <link>https://dev.to/kohanevich/is-your-ipv4-block-blacklisted-checking-a-24-the-dnsbl-way-3043</link>
      <guid>https://dev.to/kohanevich/is-your-ipv4-block-blacklisted-checking-a-24-the-dnsbl-way-3043</guid>
      <description>&lt;p&gt;If you own or lease IPv4 space, the reputation of your addresses is part of the asset. A block that's quietly listed on a major DNSBL doesn't deliver mail, fails the health checks renters run before they sign, and loses value on resale - and nothing proactively tells you it happened.&lt;/p&gt;

&lt;p&gt;Pasting one IP into a web form is fine for a spot check. If you're responsible for a whole block, here's how to actually query the reputation data and sweep a /24.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a DNSBL lookup works
&lt;/h2&gt;

&lt;p&gt;A DNSBL (DNS-based blocklist, aka RBL) answers reputation queries over DNS. You reverse the octets of the IP, append the zone, and do an &lt;code&gt;A&lt;/code&gt; lookup. A &lt;code&gt;127.0.0.x&lt;/code&gt; answer means listed; &lt;code&gt;NXDOMAIN&lt;/code&gt; means clean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 203.0.113.5  -&amp;gt;  5.113.0.203&lt;/span&gt;
dig +short 5.113.0.203.zen.spamhaus.org
&lt;span class="c"&gt;# 127.0.0.x      = listed (the code tells you which list)&lt;/span&gt;
&lt;span class="c"&gt;# empty/NXDOMAIN = not listed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Spamhaus ZEN (their combined zone: SBL + CSS + XBL + PBL), the return code tells you &lt;em&gt;which&lt;/em&gt; list you're on:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Return code&lt;/th&gt;
&lt;th&gt;List&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;127.0.0.2&lt;/td&gt;
&lt;td&gt;SBL&lt;/td&gt;
&lt;td&gt;Manually listed spam/abuse source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;127.0.0.3&lt;/td&gt;
&lt;td&gt;SBL CSS&lt;/td&gt;
&lt;td&gt;Auto-detected low-reputation sender&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;127.0.0.4 - .7&lt;/td&gt;
&lt;td&gt;XBL&lt;/td&gt;
&lt;td&gt;Compromised host / open proxy / botnet (the old CBL data lives here now)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;127.0.0.9&lt;/td&gt;
&lt;td&gt;SBL&lt;/td&gt;
&lt;td&gt;DROP/EDROP - hijacked or fully malicious range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;127.0.0.10 / .11&lt;/td&gt;
&lt;td&gt;PBL&lt;/td&gt;
&lt;td&gt;Range that shouldn't send mail directly (often normal)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;One gotcha that trips people up:&lt;/strong&gt; Spamhaus's free public mirrors block queries coming from public/open resolvers like &lt;code&gt;8.8.8.8&lt;/code&gt; and &lt;code&gt;1.1.1.1&lt;/code&gt;, and return an error code in the &lt;code&gt;127.255.255.x&lt;/code&gt; range instead of real data. Run your checks through your own resolver, or grab a free Data Query Service (DQS) key and query the DQS zone. If you &lt;code&gt;dig&lt;/code&gt; through Google's resolver and get a strange answer, that's why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sweeping a whole /24
&lt;/h2&gt;

&lt;p&gt;Once the query format makes sense, looping over the host range is trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Sweep 203.0.113.0/24 against Spamhaus ZEN&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 254&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;ans&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;.113.0.203.zen.spamhaus.org"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ans&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"203.0.113.&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$ans&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Same resolver caveat applies - for a real sweep, point it at a resolver that isn't a public mirror.)&lt;/p&gt;

&lt;h2&gt;
  
  
  AbuseIPDB for aggregate scoring
&lt;/h2&gt;

&lt;p&gt;Spamhaus tells you listed/not-listed. AbuseIPDB gives you a crowdsourced &lt;em&gt;confidence&lt;/em&gt; score (0-100) per address, and its &lt;code&gt;check-block&lt;/code&gt; endpoint scores a whole subnet in one call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-G&lt;/span&gt; https://api.abuseipdb.com/api/v2/check-block &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s2"&gt;"network=203.0.113.0/24"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;maxAgeInDays&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;90 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Key: &lt;/span&gt;&lt;span class="nv"&gt;$ABUSEIPDB_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response lists every reported address in the block with its &lt;code&gt;abuseConfidenceScore&lt;/code&gt;. AbuseIPDB treats anything under 25 as noise; 75-100 is the range you'd actually block on. The free tier is 1,000 checks/day, and &lt;code&gt;check-block&lt;/code&gt; is capped at /24 - for a larger block, iterate over its /24s or use a paid tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with a hit
&lt;/h2&gt;

&lt;p&gt;Two rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fix the root cause before you request removal.&lt;/strong&gt; Delisting while the open relay, compromised host, or spam source is still live just gets you relisted - sometimes with self-service removal disabled the next time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never pay for delisting.&lt;/strong&gt; It's free everywhere. The return code points you at the path: SBL needs the owner-of-record or ISP to contact Spamhaus; XBL/CSS is self-service via &lt;code&gt;check.spamhaus.org&lt;/code&gt;; AbuseIPDB decays over time or you dispute; Barracuda has a manual removal form. Timelines run from minutes (PBL) to weeks (AbuseIPDB decay).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While you're in there, confirm the boring hygiene that keeps a block off lists in the first place: clean, consistent &lt;strong&gt;rDNS&lt;/strong&gt;, valid &lt;strong&gt;RPKI/ROA&lt;/strong&gt; so the origin checks out, and an &lt;code&gt;abuse@&lt;/code&gt; address that someone actually reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part the sweep doesn't solve
&lt;/h2&gt;

&lt;p&gt;A sweep is a point-in-time snapshot. It tells you the block is clean &lt;em&gt;now&lt;/em&gt;. The moment you lease it out, reputation becomes a function of what your renter does - and a single compromised host or one spam run can list addresses within hours.&lt;/p&gt;

&lt;p&gt;Keeping a leased block clean is therefore continuous, not a one-off: screen who you hand a block to, watch abuse signals in real time, and de-provision fast enough that a listing never takes hold. That's most of the operational reason we built IPbnb the way we did - when a block is leased through the marketplace, that screening and monitoring runs in the background instead of landing on the owner. It won't scrub an existing listing, and no setup makes a block un-flaggable, but it keeps the day-to-day abuse-watching automated while the block earns.&lt;/p&gt;

&lt;p&gt;Either way: before you lease or sell a block, sweep it. It's a few minutes of &lt;code&gt;dig&lt;/code&gt; and one API call.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Full guide - every tool, return code, and delisting path by database:&lt;/strong&gt; &lt;a href="https://ipbnb.com/blog/ip-abuse-check-ipv4-blacklisted" rel="noopener noreferrer"&gt;https://ipbnb.com/blog/ip-abuse-check-ipv4-blacklisted&lt;/a&gt;&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>Whitelisting leased IPv4 blocks: 3 gotchas owned-space guides skip</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Fri, 05 Jun 2026 13:47:29 +0000</pubDate>
      <link>https://dev.to/kohanevich/whitelisting-leased-ipv4-blocks-3-gotchas-owned-space-guides-skip-394k</link>
      <guid>https://dev.to/kohanevich/whitelisting-leased-ipv4-blocks-3-gotchas-owned-space-guides-skip-394k</guid>
      <description>&lt;p&gt;IP whitelisting is the oldest trick in the access-control book: deny everything, allow a known set of source IPs, done. The firewall mechanics don't care whether the addresses behind your allowlist are owned or leased.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;operational&lt;/em&gt; reality does. I run a leasing platform, so I see where leased IP whitelisting quietly breaks - and it's never the firewall syntax. It's three things owned space lets you ignore.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. You inherit a reputation you didn't earn
&lt;/h2&gt;

&lt;p&gt;A leased block usually has a past. If a previous renter spammed, scanned, or landed on Spamhaus / AbuseIPDB, that history can still cling to the addresses when they reach you.&lt;/p&gt;

&lt;p&gt;Why it bites whitelisting specifically: half the time &lt;em&gt;you're&lt;/em&gt; the one trying to get whitelisted - by a customer's firewall, a payment gateway, a partner API, an SMTP relay. Their automated reputation checks see a flagged range and quietly refuse, throttle, or shove you into extra verification. Your allowlist can be perfect and you still don't get onto theirs.&lt;/p&gt;

&lt;p&gt;Fix: start from a clean, vetted block, and re-check your own block's reputation on a schedule - it drifts, including from your own workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The lease has a clock; your allowlist doesn't know that
&lt;/h2&gt;

&lt;p&gt;Owned IPs are yours indefinitely. A leased block is yours for a term. So any long-lived allowlist entry referencing leased space - yours sitting in a partner's firewall, or theirs sitting in yours - goes stale the moment that lease ends and the block gets reassigned.&lt;/p&gt;

&lt;p&gt;An allowlist entry that outlives the lease behind it isn't dead weight. It's an open door to whoever holds the block next.&lt;/p&gt;

&lt;p&gt;Treat the lease end date as a real event in your firewall lifecycle. Tag every leased-range entry with its expiry and review it then.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. RPKI sits &lt;em&gt;upstream&lt;/em&gt; of your firewall
&lt;/h2&gt;

&lt;p&gt;A firewall allowlist filters traffic that already arrived. It does nothing to make the prefix route to you. If the ROA is missing or wrong, networks doing route origin validation drop your announcement - and now there's no traffic to whitelist in the first place.&lt;/p&gt;

&lt;p&gt;If you're bringing the leased block to a cloud via BYOIP, the ROA has to authorise that provider's ASN or it won't advertise at all. RPKI is a prerequisite, not an alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring part that actually matters
&lt;/h2&gt;

&lt;p&gt;The cross-cloud best practice is the same everywhere: &lt;strong&gt;reference reusable objects, never hard-code CIDRs into individual rules.&lt;/strong&gt; That's what turns an end-of-lease change from a risky sweep into a one-line edit.&lt;/p&gt;

&lt;p&gt;On AWS, that's a customer-managed prefix list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# define trusted sources once&lt;/span&gt;
aws ec2 create-managed-prefix-list &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prefix-list-name&lt;/span&gt; trusted-sources &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--address-family&lt;/span&gt; IPv4 &lt;span class="nt"&gt;--max-entries&lt;/span&gt; 20 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--entries&lt;/span&gt; &lt;span class="nv"&gt;Cidr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;203.0.113.0/24,Description&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"partner-api"&lt;/span&gt;

&lt;span class="c"&gt;# reference it from the security group - not the raw CIDR&lt;/span&gt;
aws ec2 authorize-security-group-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-id&lt;/span&gt; sg-0abc &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ip-permissions&lt;/span&gt; &lt;span class="nv"&gt;IpProtocol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tcp,FromPort&lt;span class="o"&gt;=&lt;/span&gt;443,ToPort&lt;span class="o"&gt;=&lt;/span&gt;443,&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;PrefixListIds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'[{PrefixListId=pl-0def,Description="HTTPS from partners"}]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the range later? Edit the prefix list once; every referencing rule follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GCP:&lt;/strong&gt; network / hierarchical firewall policies (Cloud NGFW), targeting workloads with IAM-governed tags instead of raw IPs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure:&lt;/strong&gt; NSGs (rules evaluated lowest-priority-number first) plus ASGs to group your own backends by role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the usual reminder: an IP proves &lt;em&gt;where&lt;/em&gt; a packet looks like it came from, not &lt;em&gt;who&lt;/em&gt; sent it. Pair the allowlist with real auth (mTLS, certs, an IdP). Whitelisting narrows the door; it doesn't check ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  On automation - a quick critical take
&lt;/h2&gt;

&lt;p&gt;"Automate your allowlists" is good advice for &lt;em&gt;distribution&lt;/em&gt;: define ranges as code, sync from one reviewed source of truth, stop editing the same rule in 20 places. &lt;/p&gt;

&lt;p&gt;But watch the failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto-discovery&lt;/strong&gt; that &lt;em&gt;adds&lt;/em&gt; IPs from a live feed grows your trusted set with nobody reviewing it - that's deny-by-default inverted.&lt;/li&gt;
&lt;li&gt;A pipeline that can push a CIDR everywhere at once is a single blast radius for one bad entry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-healing&lt;/strong&gt; reconciliation will cheerfully re-add an entry you deliberately removed - including a leased range you retired at lease end. Revocation has to beat reconciliation, or it isn't revocation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automate distribution; keep a human gate on what &lt;em&gt;enters&lt;/em&gt; the source of truth.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; leased IP whitelisting = standard allowlist discipline (default-deny, CIDR ranges, reusable objects, real auth, audits) + three leased-only rules: start clean, keep RPKI/ROA correct upstream, and diary the lease boundary.&lt;/p&gt;

&lt;p&gt;Longer write-up with the full per-provider setup here → &lt;a href="https://ipbnb.com/blog/ip-whitelisting-leased-ipv4" rel="noopener noreferrer"&gt;IP Whitelisting Best Practices for Leased IPv4 Blocks&lt;/a&gt;&lt;/p&gt;

</description>
      <category>networking</category>
      <category>security</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
    <item>
      <title>IPv4 in 2026: Three Practical Positions for RIPE Operators</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Tue, 02 Jun 2026 11:18:42 +0000</pubDate>
      <link>https://dev.to/kohanevich/ipv4-in-2026-three-practical-positions-for-ripe-operators-n88</link>
      <guid>https://dev.to/kohanevich/ipv4-in-2026-three-practical-positions-for-ripe-operators-n88</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; If you run a network in the RIPE region, you're probably either sitting on idle IPv4, short of it, or in a position to lease it to others under your own brand. Here's what each option looks like operationally.&lt;/p&gt;




&lt;p&gt;Picture two operators at the same NOG meeting.&lt;/p&gt;

&lt;p&gt;One runs a regional ISP that moved its core behind IPv6 and CGNAT a few years back. A legacy /18 is still announced - just enough to hold the allocation - but it carries no real traffic and has earned nothing since the redesign. Clean, registered, idle.&lt;/p&gt;

&lt;p&gt;The other runs a growing access network and is out of address space. New subscribers sit behind CGNAT, and the support queue fills with the usual symptoms: broken inbound connections, IPsec and gaming complaints, mail reputation problems. Their only official supply option is a slot on the RIPE waiting list.&lt;/p&gt;

&lt;p&gt;They're each other's answer. The thing standing between them is infrastructure - LOAs, ROAs, routing, reputation checks, billing, contracts. That's the IPv4 secondary market in one sentence.&lt;/p&gt;

&lt;p&gt;If you operate in the RIPE region, you're probably closer to one of these two than you think - and often you're both. Three positions you can take:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Monetize idle IPv4
&lt;/h2&gt;

&lt;p&gt;A lot of RIPE members hold legacy space that went quiet after a redesign or an IPv6 migration. At roughly $80/month for a /24 (about $0.31 per address), a dormant /20 brings in around $1,270/month and a /16 around $20,300 - on infrastructure you already own and pay the flat RIPE fee to register.&lt;/p&gt;

&lt;p&gt;With sale prices at multi-year lows, leasing usually beats selling: income now, asset retained, no added registry cost. The common blockers - blacklist history, a messy RIPE/whois record, RPKI not configured - are routine cleanup, not dealbreakers. Typical sequence: audit and reputation check, then correct the records, set up RPKI with valid ROAs, and clear any blacklist entries. After that the subnet is ready to earn.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Lease the IPv4 you need
&lt;/h2&gt;

&lt;p&gt;RIPE's free pool has been gone since November 2019. The waiting list isn't a real supply channel - a single /24, a 12-24 month wait, hundreds of LIRs queued, and no timing guarantee. For adding subscribers this quarter, it's not a plan.&lt;/p&gt;

&lt;p&gt;CGNAT covers the gap but carries a real operational cost: port exhaustion, broken applications, abuse attribution headaches, geolocation problems, and the support load that follows.&lt;/p&gt;

&lt;p&gt;Leasing is the standard OPEX answer now. On the wire, leased space behaves exactly like owned space: announce the prefix from your ASN with a valid ROA and a matching LOA, and RPKI-validating peers treat it no differently. There's no 24-month transfer hold, and no large up-front payment locked into an asset while prices are still moving.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Resell IPv4 leasing under your own brand
&lt;/h2&gt;

&lt;p&gt;The one most operators overlook. If you already run a network, you have what an IP leasing business needs: client trust, working billing and support, regional relationships, and often your own address space. What's missing is the platform layer - listing and matching, compliance, reputation and delisting tooling.&lt;/p&gt;

&lt;p&gt;A white-label setup supplies that layer behind your brand. You lease to your own customers, bundle space with connectivity or hosting, and keep the margin instead of referring it out. Data centers and hosting providers fit this cleanly - it's an extension of what they already sell to colocation and hosting tenants. You stop being a buyer or seller in someone else's marketplace and become the marketplace.&lt;/p&gt;

&lt;p&gt;Across all three, the specialist work is the same - registry cleanup, compliance, routing, abuse monitoring - and it can sit with a platform partner rather than on your team. You don't have to become an IPv4 specialist to work this market.&lt;/p&gt;

&lt;p&gt;The infrastructure to connect the two operators in that room finally exists. The only real question is whether you use it actively or keep reacting to the shortage.&lt;/p&gt;




&lt;p&gt;Full write-up, with the complete breakdown of each path: &lt;a href="https://ipbnb.com/blog/ipv4-for-nog-2026" rel="noopener noreferrer"&gt;ipbnb.com/blog/ipv4-for-nog-2026&lt;/a&gt;&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>devops</category>
      <category>webmonetization</category>
    </item>
    <item>
      <title>Migrating to Leased IPv4 Without Downtime - The Bits That Actually Matter published</title>
      <dc:creator>Artem Kohanevich</dc:creator>
      <pubDate>Thu, 28 May 2026 10:47:37 +0000</pubDate>
      <link>https://dev.to/kohanevich/migrating-to-leased-ipv4-without-downtime-the-bits-that-actually-matterpublished-569b</link>
      <guid>https://dev.to/kohanevich/migrating-to-leased-ipv4-without-downtime-the-bits-that-actually-matterpublished-569b</guid>
      <description>&lt;p&gt;I run a platform where IP owners lease IPv4 subnets to IP renters across the RIPE region. Which means I've watched a lot of migrations - clean ones and messy ones. The messy ones almost always fail for the same reasons.&lt;/p&gt;

&lt;p&gt;This isn't a comprehensive guide. It's the list of things that trip people up when they know the basics but miss the details.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Lower TTL before you think you need to
&lt;/h2&gt;

&lt;p&gt;If your DNS records have a TTL of 86400 (24 hours) and you lower it an hour before migration, you'll spend the next 23 hours with traffic split across two addresses. If the old subnet goes offline during that window, part of that traffic simply disappears.&lt;/p&gt;

&lt;p&gt;Rule: lower TTL at least one full TTL cycle before your migration window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check your current TTL before doing anything&lt;/span&gt;
dig A yourdomain.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A1&lt;/span&gt; &lt;span class="s2"&gt;"ANSWER SECTION"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Target TTL for migration: 300 seconds. For critical records, go as low as 60.&lt;/p&gt;

&lt;p&gt;After migration is stable, raise it back. Low TTL means more DNS queries hitting your nameservers - it's not a permanent setting.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. PTR records don't update themselves
&lt;/h2&gt;

&lt;p&gt;This one catches people off guard. Reverse DNS for leased IPv4 subnets is managed by the IP owner, not the IP renter.&lt;/p&gt;

&lt;p&gt;In the RIPE region, the IP owner (or the LIR managing the resource) needs to create a &lt;code&gt;domain&lt;/code&gt; object in the RIPE database that delegates the reverse zone to your nameservers. That's not something you can do yourself, and it doesn't happen automatically when you lease a subnet.&lt;/p&gt;

&lt;p&gt;Coordinate this with your IP owner during pre-migration planning. Not on cutover day.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. RPKI: UNKNOWN and INVALID are not the same problem
&lt;/h2&gt;

&lt;p&gt;If you're announcing your leased prefix via BGP, you need a ROA (Route Origin Authorization). The ROA is created by the IP owner - not by you.&lt;/p&gt;

&lt;p&gt;Two states worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UNKNOWN&lt;/strong&gt; - no ROA exists for the prefix. Most networks accept this, but conservative peers may filter it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INVALID&lt;/strong&gt; - a ROA exists but with the wrong ASN or wrong maximum prefix length. Networks actively drop INVALID prefixes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check your ROA status before migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Using the RIPE NCC validator or Routinator&lt;/span&gt;
&lt;span class="c"&gt;# Or check via Cloudflare's RPKI toolkit&lt;/span&gt;
&lt;span class="c"&gt;# https://rpki.cloudflare.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your prefix is INVALID, you have a misconfiguration to fix. If it's UNKNOWN, you need a ROA created - talk to your IP owner.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The /24 rule - don't skip this
&lt;/h2&gt;

&lt;p&gt;If your leased block is smaller than /24 (a /25, /26, or anything longer) - you cannot announce it independently via BGP to the internet.&lt;/p&gt;

&lt;p&gt;Most upstream providers and IXP route servers filter prefixes longer than /24. The announcement won't be rejected with an error. It will just silently not propagate. Your ROA can be perfect, your IRR objects correct, your BGP session up - and the prefix still goes nowhere.&lt;/p&gt;

&lt;p&gt;If your leased block is smaller than /24, talk to your IP owner about aggregate announcement options before planning a BGP-based migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Run parallel, not sequential
&lt;/h2&gt;

&lt;p&gt;The safest migration is always: bring up the new subnet fully, validate everything, then drain traffic from the old one. Never the other way around.&lt;/p&gt;

&lt;p&gt;Checklist before DNS cutover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Services responding on new IPs&lt;/li&gt;
&lt;li&gt;[ ] BGP prefix visible from multiple vantage points (check RIPE RIS or BGPView)&lt;/li&gt;
&lt;li&gt;[ ] Monitoring active on new subnet&lt;/li&gt;
&lt;li&gt;[ ] PTR delegation live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After DNS update, watch traffic on both subnets. Decommission the old one only when traffic has dropped to zero - and then wait another 24-48 hours before pulling it fully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify DNS propagation from multiple resolvers&lt;/span&gt;
dig A yourdomain.com @8.8.8.8
dig A yourdomain.com @1.1.1.1
dig A yourdomain.com @9.9.9.9

&lt;span class="c"&gt;# Verify routing path to new subnet&lt;/span&gt;
mtr &lt;span class="nt"&gt;-rn&lt;/span&gt; yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Post-migration reputation monitoring
&lt;/h2&gt;

&lt;p&gt;A clean leased subnet can pick up a blacklist entry fast if something on your infrastructure is misconfigured - an open relay, a proxy, a compromised service.&lt;/p&gt;

&lt;p&gt;Check at 24h, 72h, and one week after migration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spamhaus (SBL, XBL, PBL) - critical if you're sending email&lt;/li&gt;
&lt;li&gt;Talos Intelligence&lt;/li&gt;
&lt;li&gt;AbuseIPDB&lt;/li&gt;
&lt;li&gt;MXToolbox for a consolidated view&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you appear on a list, the cause is almost always something on your end - not a history problem with the block itself.&lt;/p&gt;




&lt;p&gt;That's the short version. If you want the full breakdown - DNS TTL timing in detail, BGP announcement setup with RPKI and IRR specifics, step-by-step migration phases, and BYOIP configuration for AWS, GCP, and Azure - I wrote a longer guide on the IPbnb blog:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ipbnb.com/blog/migrate-to-leased-ipv4-zero-downtime" rel="noopener noreferrer"&gt;How to Migrate Your IP Infrastructure to Leased IPv4 Without Downtime&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments.&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>devops</category>
      <category>networking</category>
    </item>
  </channel>
</rss>
