Limitless Networking

Using my own public IP space on a regular internet connection with a Juniper SRX

Recently I purchased new servers for my home lab (topic for more posts to follow when everything is fully done). I wanted to use these servers to run a number of workloads (mainly virtual machines) and I wanted to use the public IP space I recently got for that. Of course my consumer internet connection does not support setting up BGP and I did not want to spend a lot more money on a ‘business internet’ option.

I was discussing this with a friend and he offered me to use the router in a co-location he has. This allowed me to set-up a GRE tunnel to the router and advertise my prefix. Resulting in the following topology:

In the initial set-up I’m using a virtual firewall, as I’m moving my home lab in a few months and want to deploy this on a physical firewall then. My first attempt was to use pfSense. I’ve been using pfSense in the past a lot with great pleasure. It has great firewall, NAT and VPN features, but routing is not its strongest. I was successful in setting up OpenBGPd, but I found the GUI integration limited. The GRE tunnelling support was where I got stuck. One important missing piece on the pfSense part was that it is not possible to configure IPv6 addresses on the GRE tunnel interface (overlay IP addresses). I managed to get it working on link-local addresses, but this required special static routes to be added and I didn’t think it was an elegant solution. Without having proper overview of the functioning of the system (both on the GRE tunnel and the BGP part) I abandoned the pfSense option.

vSRX

I then deployed a Juniper vSRX firewall. Now this is not a free option, but as I work for Juniper, I really liked having Junos at this critical place in my own home network. I’m using the 60-day trial license that anyone can get, including the latest virtual appliances on the Juniper website (https://www.juniper.net/us/en/dm/free-vsrx-trial/). In the final set-up I’m probably going to use a SRX300 physical appliance that should give me enough forwarding performance for my 500/40Mbps cable connection.

In the past the vSRX was based on a FreeBSD VM running on top of a Linux guest OS. Where the data-plane processes were running on top of Linux to utilise DPDK to accelerate packet processing.

vSRX2 architecture

This enabled the use of much better multi-core processing support in the Linux kernel, while still using the FreeBSD based Junos OS. The downside was that booting the appliance took a lot of time (7-10 minutes). It also required to have ‘Promiscuous mode’ enabled to connect to the fxp0 out-of-band management interface, as this was a virtual NIC with another mac address inside the FreeBSD VM.

The latest version of vSRX called vSRX3 or vSRX 3.0 surprisingly does not use Linux anymore, but is fully based on FreeBSD 11. Making use of the improvements in FreeBSD regarding multi-core processing and support for DPDK. It also means that performance did not change (may have even improved in some cases) when this transition was made and greatly improving boot times (about a minute now). Even with only 2 CPU cores (still separating control- and data-plane processes) the vSRX performs great and is well suited for my use case.

vSRX3 architecture

As there is no virtual machine involved in this architecture. The fxp0 interface is reachable again without having to enable Promiscuous mode in ESXi environments.

My set-up did not require the use of more advanced features like SR-IOV, because my bandwidth requirements are considered quite low (1Gbps is more than enough for my home network!)

Tip: To know the difference if you are running a vSRX3 or a previous generation, take a look at the output of ‘show version’. If ‘vSRX’ is written with uppercase letters you are running vSRX3, if ‘vsrx’ is written in all lowercase, you are running a previous generation.

Fun fact: Did you know the first version of this product was called Firefly Perimeter?

Diagrams and more details found at: https://www.juniper.net/documentation/en_US/vsrx/information-products/topic-collections/release-notes/19.1/topic-98044.html#jd0e101

GRE configuration

The set-up for GRE and BGP is rather simple if you are used to Junos configuration. The GRE tunnel interface is available on the vSRX by default and no configuration is necessary to enable it.

First I configured the GRE interface. The important part here is that I ran into some MTU/fragmentation issues as I am transiting a default 1500 byte MTU infrastructure (also known as the Internet ;). Which is why I enabled the allow-fragmentation and clear-dont-fragment-bit knobs. As I will want to have all my internet facing traffic to use the GRE tunnel, the only routing configuration I need is to know where to find the GRE tunnel destination. This is why a /32 static route is configured.

All IP addressing used in these examples are specified as prefixes used for documentation.

interfaces {
gr-0/0/0 {
unit 0 {
clear-dont-fragment-bit;
description "GRE to Colo";
tunnel {
source 203.0.113.1;
destination 198.51.100.1;
allow-fragmentation;
}
family inet {
mtu 1476;
address 192.0.2.253/31;
}
family inet6 {
mtu 1476;
address 2001:db8:1::1/64;
}
}
}
}
routing-options {
static {
route 198.51.100.1/32 next-hop 203.0.113.2;
}
}

As the GRE interface is just a regular interface, we should configure this interface to belong to a security zone. In this case it’s my untrust zone as I connect directly to the Internet. I allow BGP traffic to access this interface as we will configure this later. I do not include any security policy configuration here, as they are just default (allow all traffic from trust to untrust).

security {
flow {
tcp-mss {
all-tcp {
mss 1340;
}
}
}
zones {
security-zone untrust {
interfaces {
gr-0/0/0.0 {
host-inbound-traffic {
protocols {
bgp;
}
}
}
}
}
}
}

One key knob here is that I have to specify a TCP MSS value that is much lower than normal. This is because I need to account for a GRE+IP header overhead, but I also have an IPsec tunnel configured that adds overhead. There are special commands here to just change the MSS size for GRE tunnels, but they are designed for the GRE over IPsec use-case. This is IPsec over GRE.

In my case an MSS size of 1366 works, but this is not an easy job to determine, as the ESP overhead on a packet varies on the packet size. I tried an ICMP ping with DF-bit set and up to 1378 bytes, my ping reply came back. This means 1378 + ICMP (8b) + IP (20b) = 1406 bytes, or 94 bytes of total overhead

MSS: MTU – IP (20b) – TCP (20b) = 1460 bytes – All-overhead (94b) = 1366 bytes

Cisco has a great IPsec overhead calculator https://cway.cisco.com/ipsec-overhead-calculator/

Online I found varying safe numbers. I’ve set it to 1340 to also accommodate the additional 20 bytes on an IPv6 header. Please comment below your recommendation for MSS size!

BGP configuration

Finally it’s time to set-up some dynamic routing. In this case, as I wanted to advertise my own Autonomous System (AS) as well. I wanted to originate BGP from my house and the router in the co-location to act as transit provider for me. So let’s setup a pretty standard EBGP configuration. Again BGP is included in any vSRX license.

protocols {
bgp {
group colo-v4 {
type external;
import colo-ipv4-in;
family inet {
unicast;
}
export colo-ipv4-out;
peer-as 65001;
neighbor 192.0.2.254;
}
group colo-v6 {
type external;
import colo-ipv6-in;
family inet6 {
unicast;
}
export colo-ipv6-out;
peer-as 65001;
neighbor 2001:db8:1::2;
}
log-updown;
}
}
routing-options {
router-id 192.0.2.1;
autonomous-system 64999;
}

As BGP is already specified as host-inbound-traffic in the security zones configuration, no additional policy is required. This does mean that all BGP traffic is allowed. Of course it’s best practice to limit the source address of the BGP traffic to only the neighbors configured. For that the vSRX supports regular control plane security by applying a firewall filter configuration to the Loopback interface (no IP address required if you don’t want it). 

Of course policies are the most important part of any BGP configuration. I’m not interested in receiving a full BGP table so a default route will do fine for both IPv4 and IPv6. Second I need to advertise my own IP space from my own AS. To originate the prefixes I created 2 static routes to advertise the entire subnet, so I can use that later.

policy-options {
policy-statement colo-ipv4-in {
term allow-default {
from {
route-filter 0.0.0.0/0 exact;
}
then accept;
}
then reject;
}
policy-statement colo-ipv4-out {
term my-subnet {
from {
protocol static;
route-filter 192.0.2.0/24 exact;
}
then accept;
}
then reject;
}
policy-statement colo-ipv6-in {
term allow-default {
from {
route-filter ::/0 exact;
}
then accept;
}
then reject;
}
policy-statement colo-ipv6-out {
term my-subnet {
from {
protocol static;
route-filter 2001:db8:abc::/48 exact;
}
then accept;
}
then reject;
}
}
routing-options {
rib inet6.0 {
static {
route 2001:db8:abc::/48 discard;
}
}
static {
route 192.0.2.0/24 discard;
}
}

RIPE

Now establishing a dynamic routing configuration is one thing. To have your prefix be accepted by any upstream networks, you have to make sure your administration is in place. As I live in Europe, my IP resources come from RIPE. 

By the way: If you want to learn more on RIPE, RIPE NCC and Routing Security, make sure you listen to the episode of the Routing Table podcast we recorded with Nathalie Trenaman on these topics!

You have to make sure there is a ROUTE object created for your prefixes which also specifies what the origin AS will be for these prefixes. While you are there and signed in anyway, make sure you also create ROA objects so RPKI will mark your prefixes as valid when they originate your AS!

Most providers will have some form of filtering applied to their peers, which means that I also had to make sure that my upstream provider accepted my AS and prefixes. This meant that I had to be included in the AS-SET object of my upstream provider.

I typically use the bgpq3 tool to verify if my objects are correctly set (no guarantees, as your providers can use different tools to collect this information)

NAT

Now to finally make use of the prefix now it’s advertised and accepted. I set-up a simple source NAT rule so my egress traffic uses an IP address in my own subnet as source for browsing the web.

The SRX has a default source NAT rule in place to accept all traffic from the trust zone going to untrust and use the interface IP address as source IP. This I want to have changed to an IP from my own subnet, which requires a pool to be created (even it’s only 1 IP that everything is translated to).

security {
nat {
source {
pool internet {
address {
192.0.2.1/32;
}
}
rule-set trust-to-untrust {
from zone trust;
to zone untrust;
rule all-trust {
match {
source-address 0.0.0.0/0;
}
then {
source-nat {
pool {
internet;
}
}
}
}
}
}
}
}

Done!?

Now I can browse the internet from my own IP space from my own home internet connection!

Stay tuned for another blog about the funny limitation I ran into when I configured an IPsec VPN. That required having to reconstruct quite a bit of this set-up to work around it!

 

4 Comments

  1. Faheem Khan

    I guess it would be every network engineer’s dream to have their own AS together with a nice /24 prefix publicly routable on the internet. Wait, better yet, host your own mini data center along with that as well 🙂 But I guess we can always mimic most of that in EVE-NG.
    Nonetheless very interesting, thanks for sharing this Rick, and looking forward to more posts in the future!

    • Rick Mur

      Thanks! Much appreciated. It has always been my dream to have my own prefix. It’s so cool to see your own name as ‘ISP’ 🙂

  2. Melchior Aelmans

    Awesome blog! Thanks for the write up.

    Also a big thanks for suggesting folks to create ROAs.
    One more thing I would love to see is that you would implement BGP Origin Validation on your side as well so you are safe too!

    Cheers and keep up the good work!!

    • Rick Mur

      Thanks!! If I would allow anything other than a default route, I would certainly validate :)!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2024 Rick Mur

Theme by Anders NorenUp ↑