Do you know that you can actually run your own LTE network at home? In the US, there’s a CBRS (Citizens Broadband Radio Service) band that is designed to be shared which correspond to LTE band 48. Someone wrote a great write up1 on exactly how to do just that.
LTE network has always fascinated me because it is previously inaccessible to set one up by yourself and also pretty complicated by design as well and this provides a great way to start exploring what it actually means to set one up and to start understanding how exactly does it work for a DIYer like me.
This post documents my experience following the original article and highlight some differences that I encountered.
How did it go?
Acquiring a eNodeB
The base stations are still available on eBay by searching for CBRS
like the original article mentioned. I did ran into a potential scam that offered one for $50 and happened to be a local pickup. Once I paid for it, the seller wanted to ship by next week and mentioned it’s actually not local, and well, they did not ship it and just ghosted me, I had to request refund from eBay and fortunately did have the money back. I did made another purchase from another eBay seller at around $100 and this time it did arrive.
🔼 The eNodeB itself is actually quiet a unit. It has the surface size of half of a 13” MacBook Pro.
Other base station options?
I tried to search for other eNodeB options. SCE4255W
is not exactly “readily available” (aka off Amazon) outside of the second-hand Helium FreedomFi version and the one that’s on sale goes for $999 to $1999, so buying it second hand is still the only way to get it cheap, with the downside of needing to do some DNS hijacking as the TR-069 server is hardcoded in the firmware.
Moso Networks is one of the company that is still working in the CBRS land and they do offer a 5G gNodeB (5GID2), it is unclear how much it would actually cost and/or if they would sell you just one though.
Setting up Magma
Following the instructions from the linked articles, it mostly worked. I already have a mini PC that runs a nomad node for various workloads at home so I choose to upgrade it to 32GB ram, then wipe that node and put Proxmox VE on it.
Setting up Proxmox VE
Proxmox VE is one of the easier way to manage multiple VMs on network machines and suits our use case here.
I ran into a weird case where my Proxmox VE host would just go offline if I start any VM on it. It turned out that was because I had forced the PC to have a specific VLAN in my router (UniFi, in its term, this is setup in the Client Device section).
To fix it, I remove the override from UniFi and instead setup the Switch port to tag the VLAN I wanted for my nomad workload by default and allow other tagged frames to go through as we’ll need a separate VLAN for eNodeB later. I’ve also setup the VMs to carry that right tag in Proxmox VE as well.
Magma Core
Magma started as Facebook’s open-source project but later took over by the Linux Foundation. It is an open-source implementation of 4G/5G network components. We’ll need two VMs to setup Magma here.
Instead of 1.8.0 mentioned in the article, I used 1.9.0 and ran it on Ubuntu Server 25.04. I followed the article’s setup steps except that I had to patch fluentd’s Dockerfile. Edit ~/magma/orc8r/cloud/docker/fluentd/Dockerfile
and update it to:
# ...
RUN gem install \
multi_json:1.15.0 \
excon:1.2.5 \
elasticsearch:7.13.0 \
# ...
Those gems has been updated past supporting the Ruby version shipped in fluentd image so we need to pin it to an older version.
I used AdGuard Home on my network so I just added the DNS hijacking rules there: *.magma.test -> [magma core VM IP]
.
Magma Access Gateway
The access gateway is the more complicated VM to setup. It requires 2 network interface:
- one for the
S1
interface which is used to connect to eNodeB: I set this up on my network with another VLAN and change the native VLAN for the port that I’ll plug my eNodeB in to use that VLAN. Magma will run DHCP/DNS server on this interface, so in UniFi, I setup the VLAN as a Third-party Gateway network.- We also need to DNS hijack
acs.freedomfi.com
to our access gateway for TR-069 provisioning. I used the S1 interface IP here, pointing it to10.0.2.1
, since10.0.2.x
is the network the eNB will get from DHCP.
- We also need to DNS hijack
- another one called
SGi
interface which connects to the orchestrator and for all the other traffics. I just use the same internal workload VLAN that I already have for this. This interface needs internet access.
This VM NEEDS Ubuntu 20.04(.6 LTS is fine) unfortunately. I tried setting it up in newer Ubuntu and ran into issues with ansible / python versions. I also was not able to setup the agw with docker setup like the article described. I ran into issues with magmad
keep crashing due to not getting IPv6 addresses. I read the magma documents and realized they also supports bare metal deployment, so I set it up that way.
I had to force the system to use my DNS server by adding dns-nameservers [my DNS server]
to /etc/network/interfaces.d/eth0
and I ran ifdown eth0
and ifup eth0
to reset the network settings. You will also need to run systemctl restart magma@dnsd
to ensure dnsmasqd
picks up new configuration and reset its cache, in case some query has already been made to it. If all goes well, you should be able to see the access gateway checks in with the orchestrator on the NMS interface and it should show online.
At this point, plug the eNodeB in and (will need a min or two for it to boot up) type enodebd_cli.py get_all_status
to verify the eNodeB is connected via TR-069. You should be able to see everything in magma NMS if you set it up correctly as well.
Here’s what the NMS would look like if everything is setup correctly: (except the subscribers part, you will only see that once your phone is connected to it later)
Helium FreedomFi eNodeB Default Password
The default username and password are
sc_femto
andtsFid2wz
.
Check your eNB's SAS status
CBRS usage relies on SAS (Spectrum Access System) to grant spectrum access to individual user / equipment. The eNB needs to be configured to talk to SAS and receive a grant before it will start transmitting LTE signal.
Theoretically Magma’s TR-069 server should configure the eNB’s SAS access but in my case, the settings was not updated. I had to go directly into the eNB (make sure you did put the eNB’s serial in
web_ui_enable_list
) and go toManage > SAS Configuration
tab, and fill in the following:
Server: Commercial - Google
Server URL: Should be automatically updated to
https://sas.goog/v1.2/
User ID: Your Google Cloud project ID
I hooked up the GPS antenna and just use the GPS source but you can also configure the location yourself as well. Once it’s all setup, go back to the State page. You should see GPS acquired location (if you use it) and SAS state should be Authorized.
Diagnosing Magma Problems
Here are some useful resources / commands I used when I tried to solve issues with Magma AGW:
- Magma Debug Docs
- List all service logs:
journalctl -xefu "magma@*"
- Verify if eNodeB is asking for IP:
journalctl -xefu magma@dnsd
Watch out for "Private DNS"
I was confused for a bit about why I still can’t connect to my internal services that lives on my home network from my LTE network. Turned out Android has this “Private DNS” that’ll forward DNS queries on the cellular network to Google’s server instead. Remember to turn it off to use your own DNS server.
🔼 Private DNS settings in Android Settings
Setup Data Plan / APN
Magma 1.9.0 seems to have changed how the bandwidth limit is communicated. If you put in 1000000000
like mentioned in the article for bandwidth, you will get attach_reject
event later when your phone is trying to attach to the network as it failed to store the number due to uint32
overflowing as specified by its protobuf definition.
Here’s the value I put in:
- APN
- Max Required Bandwidth:
4294967295
for both upload / download
- Max Required Bandwidth:
- Data Plan
- Max Bit Rate / Download:
4000
(note the unit is Mbps) - Max Bit Rate / Upload:
2000
(note the unit is in Mbps)
- Max Bit Rate / Download:
Magma NMS actually has code to identify the 4000 / 2000
setup as unlimited and your UI should show Unlimited
once you save it.
Provision an eSIM
My blank SIM card has not arrived yet so I tried simlessly as they allow you to sign one eSIM for free (not affiliated). Sign up with their RSP portal and create a Regular configuration. (They also have a specific Private_LTE configuration but the regular one worked for me anyway, I don’t know the difference between the two choices.)
The configuration values are as follows:
- Profile name / SPN / PMN: Whatever your choice of network brand name
- HPLMN:
315010
RAT4000
- EHPLMN:
315010
- OPLMN:
315010:4000,315010:8000,315010:0080
Then you can go to the eSIM page and click “Generate AC / Single Generate” and fill in the following values:
- ICCID: For iPhone, you can find it in
Settings > General > About
and scroll down. Newer iPhones will have two ICCIDs, just pick either one. (Weirdly I ended up using this eSIM on my Android phone which would have a different ICCID but it worked anyway.) - IMSI:
315010999900001
It has to start with3150109999
as315010
is your MCC/MNC and9999
is reserved for CBRS testing according to the article (I could not find another source for this). The last00001
can be any numbers as long as it is registered in your magma NMS. - KI / OPC: These are two random 32-character hexdecimal string. You can generate one using
openssl rand -hex 16 | tr '[:lower:]' '[:upper:]'
. This needs to be the same as what you entered into magma NMS for the given IMSI.
Click Generate
and your eSIM will be provisioned right away. You can then add it to your phone by scanning the QR code. For some reason, I was not able to get it to work on my iPhone 15 but my Pixel 6 will happily take it.
Does it work?
It works! Here’s how it looked like when I’m setting it up on my Pixel 6:
![]() | ![]() | ![]() |
---|---|---|
🔼 Installing the eSIM Profile | 🔼The phone is connected to the network | 🔼Testing speed with fast.com (170 down / 14 up) |
From here…
Range wise the reach was impeccable indoor. My LTE signal can reach my wifi dead spot, my bathroom, no problem at full speed. However, once you go outside, the low mounting position and power of an indoor station makes it not very effective. It goes down to 1Mbps at about 20m (65ft) and beyond that it’s unusable or simply No Service.
So, is it practical? Not really, outside of letting me surf internet smoothly while on toilet but it is definitely fun to set one up.
Next, I’ll probably look into other core network implementation such as Open5GS
as magma is quiet something to setup and hard to maintain. I’ll probably also use this chance to dive deeper into the different components of LTE network and how APN / routing actually works behind the scene.