G4
Networking AWS

GoBGP 4.11.0 on AWS User Guide

| Product: GoBGP 4.11.0 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and verifying GoBGP 4.11.0 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened FRRouting, OpenBGPD & BGP Routing and Peering AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other routing and peering products in the listing are described on the listing's guide hub.

GoBGP is an open source implementation of BGP-4 written in Go by the osrg project. It runs as one daemon, gobgpd, configured with a TOML file and driven at runtime over a gRPC API, with a companion CLI, gobgp, for everyday operation. Because every operation is an API call, GoBGP is popular as a route server, a route reflector, an edge speaker and a route injector that software drives directly.

The image ships the pinned upstream GoBGP 4.11.0 release (gobgp_4.11.0_linux_amd64.tar.gz), verified by SHA-256 against the release's published checksums before it is unpacked. The pprof and metrics HTTP listener that gobgpd opens on localhost:6060 by default is switched off, so the instance serves no web page at all.

A bare BGP daemon has nothing to show on its own, so the image ships a self-contained reference deployment on the one instance:

  • A primary gobgpd (AS 65001), the daemon you drive with gobgp, listening for BGP on the internal address 10.255.255.1 only
  • A demo peer gobgpd (AS 65002) on the internal address 10.255.255.2
  • A real eBGP session between them, authenticated with a TCP-MD5 key generated on your instance's first boot, with routes propagating both ways and an import policy filtering one prefix

Both internal addresses live on the loopback interface, so nothing in the demo is reachable from your VPC. No external neighbor is configured: the instance talks BGP to nobody else until you add your own peers.

What is on the image:

  • GoBGP 4.11.0: the gobgpd daemon in /usr/local/bin and the gobgp CLI in /usr/local/lib/gobgp, both the unmodified upstream release binaries
  • /usr/local/bin/gobgp, a small wrapper that points the CLI at the primary daemon's API socket, so gobgp neighbor just works
  • gobgpd.service (the primary, API socket /run/gobgp/gobgpd.sock) and gobgpd-peer.service (the demo peer, API socket /run/gobgp-peer/gobgpd.sock)
  • gobgp-firstboot.service, which generates the session key and writes both configurations on first boot, and gobgp-loaddr.service, which adds the two internal addresses to lo on every boot
  • The configuration in /etc/gobgp/ and a credentials record in /root/gobgp-credentials.txt (root only)
  • The Apache-2.0 licence and the list of linked Go modules in /usr/share/doc/gobgp/, and the build evidence in /usr/share/gobgp/

Default user: ubuntu · Architecture: x86_64 · Root volume: 8 GiB gp3

Security posture

  • No BGP port on your network until you open one. Both daemons listen on their internal loopback addresses only. The listing security group opens SSH (22) only, and you open TCP 179 to your own peers when you add them.
  • Connections from anyone who is not a configured neighbor are refused. gobgpd closes a BGP connection from any address it has no [[neighbors]] block for and logs Can't find configuration for a new passive connection.
  • The gRPC API is unauthenticated, so it is never on the network. GoBGP's gRPC API has no login of its own: anyone who can connect to it can add or remove neighbors, routes and policy. On this image there is no TCP API at all. Each daemon serves its API on a Unix socket owned by root:gobgp with mode 0660, inside a 0750 directory, so only root and members of the gobgp group can open it. Every other local user is refused by the kernel (permission denied). Because the control is file permissions, not a firewall rule, flushing or replacing the nftables ruleset does not open it.
  • Per-instance session key. The TCP-MD5 key that authenticates the demo session is generated on each instance's first boot. No key ships in the image, so no two instances share one.
  • Unprivileged, sandboxed daemons. Both gobgpd processes run as the gobgp system user with only CAP_NET_BIND_SERVICE (to bind port 179) and CAP_NET_ADMIN (to set the TCP-MD5 socket option), under a systemd sandbox: a read-only file system, no access to home directories, a private /tmp and no privilege gain.
  • No metadata access for the daemons. gobgpd makes outbound connections to whatever neighbors you configure, so every GoBGP unit is blocked from reaching the instance metadata service (169.254.169.254 and fd00:ec2::254). Your peers and Amazon Time Sync (169.254.169.123) are unaffected.
  • IMDSv2 required. The AMI is registered with ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests.
  • Crash recovery and fail-closed configuration. A daemon that crashes is restarted automatically. A configuration that gobgpd --dry-run rejects leaves the unit stopped and failed instead of restarting in a loop, with nothing listening.
  • Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.

Prerequisites

  1. An AWS account and permission to launch EC2 instances
  2. An EC2 key pair in the Region you launch in
  3. A VPC subnet for the router, and the addresses and AS numbers of the peers it will talk to

Recommended instance type: m5.large. GoBGP is lightweight: each daemon of the reference deployment uses about 30 MB of memory, and a small route server or edge speaker runs comfortably on t3.small or larger. Full internet tables and many route-server clients need more memory.

Connecting to your instance

Version Operating system SSH user
GoBGP 4.11.0 on Ubuntu 24.04 Ubuntu 24.04 LTS ubuntu

Step 1: Launch the instance

Option A: AWS Marketplace console

  1. Open the cloudimg Hardened FRRouting, OpenBGPD & BGP Routing and Peering AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  2. Once the subscription is active, choose Launch your software.
  3. Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose GoBGP 4.11.0 on Ubuntu 24.04, then choose your Region.
  4. Pick an instance type (m5.large recommended; the software charge is $0.04 per vCPU per hour) and your key pair.
  5. Security group: the listing's default group allows SSH (22) only. Restrict it to your own IP address. You will allow BGP from your peers in Step 10.
  6. Choose your VPC and subnet, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.

Option B: AWS CLI

Run this on your own workstation. It creates a security group that allows SSH from your management address only, then launches the instance. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the VPC, subnet, key pair and CIDR with your own:

SG=$(aws ec2 create-security-group --group-name gobgp-router \
  --description "GoBGP router" --vpc-id vpc-0123456789abcdef0 \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids "$SG" \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=gobgp-router}]'

You do not need --metadata-options: the AMI already makes IMDSv2 required.

Step 2: Connect and read the instance details

Connect as ubuntu with the key pair you chose:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within a minute of launch. It generates the instance's TCP-MD5 session key, writes both daemon configurations, checks each one with gobgpd --dry-run, and records the details in /root/gobgp-credentials.txt, readable by root only. It starts nothing itself: systemd starts the daemons once it has finished. The rendered configurations carry the key too, so they are readable only by root and the gobgp group:

sudo stat -c '%a %U:%G %n' /root/gobgp-credentials.txt /etc/gobgp/gobgpd.conf /etc/gobgp/gobgpd-peer.conf
sudo grep -v '^GOBGP_PEERING_MD5_KEY=' /root/gobgp-credentials.txt
600 root:root /root/gobgp-credentials.txt
640 root:gobgp /etc/gobgp/gobgpd.conf
640 root:gobgp /etc/gobgp/gobgpd-peer.conf
# GoBGP 4.11.0 on Ubuntu 24.04 - packaged by cloudimg
#
# The key below was minted on this instance's FIRST BOOT and exists nowhere else: the AMI carries no key, and the
# configurations that use it were rendered on this instance. It authenticates the demo eBGP session (TCP-MD5).
# Generated: 2026-11-09T16:57:50Z


# The reference deployment on this instance
#   Primary gobgpd (AS 65001)   gRPC unix:///run/gobgp/gobgpd.sock        drive it with: sudo gobgp ...
#   Demo peer      (AS 65002)   gRPC unix:///run/gobgp-peer/gobgpd.sock   sudo gobgp --target unix:///run/gobgp-peer/gobgpd.sock ...
#   Internal demo link          10.255.255.1 <-> 10.255.255.2 (loopback-local)
#
# The gRPC API has NO authentication, so there is no TCP API: each daemon serves it on a Unix socket owned
# root:gobgp, mode 0660. Root and members of the gobgp group can drive BGP; any other user is refused (EACCES).
# To let an operator run gobgp without sudo:  sudo usermod -aG gobgp <user>   (then log in again)
#
# Try it:  sudo gobgp neighbor     sudo gobgp global rib     sudo gobgp policy
#          sudo gobgp --target unix:///run/gobgp-peer/gobgpd.sock global rib
#
# Config: /etc/gobgp/gobgpd.conf (check with: sudo gobgpd --dry-run -f /etc/gobgp/gobgpd.conf --pprof-disable --metrics-path=)
# To peer with your own routers, see the guide: https://www.cloudimg.co.uk/guides/gobgp-4-11-0-on-ubuntu-24-04-aws/

The demo key itself is on the GOBGP_PEERING_MD5_KEY= line, which the command above leaves out. You never need it for your own peers: each real neighbor gets its own key, agreed with that peer.

Step 3: Confirm the services are running

The four units are active, gobgpd reports version 4.11.0, and the build record names the exact upstream release and its hashes. The installed binaries match the recorded hashes:

systemctl is-active gobgp-loaddr gobgp-firstboot gobgpd gobgpd-peer
gobgpd --version
cat /usr/share/gobgp/build-evidence.txt
sha256sum /usr/local/bin/gobgpd /usr/local/lib/gobgp/gobgp
active
active
active
active
gobgpd version 4.11.0
GoBGP 4.11.0 - packaged by cloudimg for AWS Marketplace
upstream repository : https://github.com/osrg/gobgp
release             : v4.11.0 (tag commit 53ceb78fe284), asset gobgp_4.11.0_linux_amd64.tar.gz
artifact sha256     : b45eefb6f8cb662740efa99631f14bac23c9ea8cca158843293a3ecb5cbc72b6 (equals the release checksums.txt line)
gobgpd sha256       : 58127efa0ff1aaeadfbb802c771b18134c401c8c16229b6d3d2ab30935f288b2
gobgp sha256        : f2a64916729cb019a6b1b8e1ff83cbf2653d93eae1c5ece498e586bf26afab93
built by upstream   : go1.27.3, CGO_ENABLED=0, -tags netgo, -ldflags=-s
licence             : Apache-2.0 (/usr/share/doc/gobgp/LICENSE); linked Go modules in /usr/share/doc/gobgp/THIRD-PARTY-MODULES.txt
58127efa0ff1aaeadfbb802c771b18134c401c8c16229b6d3d2ab30935f288b2  /usr/local/bin/gobgpd
f2a64916729cb019a6b1b8e1ff83cbf2653d93eae1c5ece498e586bf26afab93  /usr/local/lib/gobgp/gobgp

Step 4: The authenticated eBGP session is Established

gobgp neighbor lists the primary's neighbors and their state; the demo peer is Establ with two prefixes received. gobgp neighbor <address> shows the session detail:

sudo gobgp neighbor
sudo gobgp neighbor 10.255.255.2 | sed -n '1,7p'
Peer            AS  Up/Down State       |#Received  Accepted
10.255.255.2 65002 00:03:26 Establ      |        2         2
BGP neighbor is 10.255.255.2, remote AS 65002
  BGP version 4, remote router ID 10.255.255.2
  BGP state = SESSION_STATE_ESTABLISHED, up for 00:03:26
  BGP OutQ = 0, Flops = 1
  Local address is 10.255.255.1, local ASN: 65001
  Hold time is 90, keepalive interval is 30 seconds
  Configured hold time is 90, keepalive interval is 30 seconds

The session only reaches Established because both ends hold this instance's TCP-MD5 key. The API never returns the key: it is not in the gobgp neighbor output.

Step 5: Routes propagate

gobgp global rib shows the primary's routing table: it has learned 192.0.2.0/24 from the demo peer and originates 203.0.113.0/24 itself. Point the CLI at the demo peer's socket with --target to see the other direction, where 203.0.113.0/24 arrives from AS 65001:

sudo gobgp global rib -a ipv4
sudo gobgp --target unix:///run/gobgp-peer/gobgpd.sock global rib -a ipv4
   Network              Next Hop             AS_PATH              Age        Attrs
*> 192.0.2.0/24         10.255.255.2         65002                00:03:26   [{Origin: ?}]
*> 203.0.113.0/24       0.0.0.0                                   00:03:39   [{Origin: ?}]
   Network              Next Hop             AS_PATH              Age        Attrs
*> 192.0.2.0/24         0.0.0.0                                   00:03:27   [{Origin: ?}]
*> 198.51.100.0/24      0.0.0.0                                   00:03:27   [{Origin: ?}]
*> 203.0.113.0/24       10.255.255.1         65001                00:03:26   [{Origin: ?}]

GoBGP originates routes over its API rather than from the TOML file, and its RIB lives in memory. Each daemon therefore re-originates the prefixes listed in /etc/gobgp/originate-<unit>.txt every time it starts, so the routes come back after a restart. The three demo prefixes are documentation ranges (RFC 5737) that are never routed on the internet.

Step 6: The import policy filters

The primary's global import policy, reject-blackhole, rejects 198.51.100.0/24. The demo peer genuinely advertises it: the Adjacency RIB In (adj-in), which lists what the peer sent before any policy ran, includes it. It is absent from the primary's RIB in Step 5, because the policy rejected it:

sudo gobgp neighbor 10.255.255.2 adj-in -a ipv4
sudo gobgp global policy import
sudo gobgp policy prefix
   ID  Network              Next Hop             AS_PATH              Age        Attrs
   0   192.0.2.0/24         10.255.255.2         65002                00:03:26   [{Origin: ?}]
   0   198.51.100.0/24      10.255.255.2         65002                00:03:26   [{Origin: ?}]
Import policy:
Default: ROUTE_ACTION_ACCEPT
Name reject-blackhole:
    StatementName reject-198-51-100:
      Conditions:
        PrefixSet: any blackhole 
        RPKI result: UNSPECIFIED
      Actions:
         reject
NAME       PREFIX
blackhole  198.51.100.0/24 24..24

The neighbor summary in Step 4 counts both prefixes as received and accepted at the session; the global import policy is what keeps 198.51.100.0/24 out of the RIB. GoBGP applies per-neighbor import policies only to route-server clients, which is why the policy is attached to the global table.

Step 7: Secure by default

These are every TCP listener on the instance, then every Unix socket gobgpd listens on. SSH listens on all interfaces (the security group restricts it), BGP is bound to the two internal demo addresses only, and the rest are systemd-resolved's local DNS stub. There is no gRPC port (50051) and nothing on 6060:

sudo ss -Hltn | awk '{print $4}' | sort
sudo ss -Hlxp | grep gobgpd | awk '{print $5}'
0.0.0.0:22
10.255.255.1:179
10.255.255.2:179
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
/run/gobgp-peer/gobgpd.sock
/run/gobgp/gobgpd.sock

A BGP connection from an address that is not a configured neighbor is closed straight away and logged. This connects from 127.0.0.1, which has no [[neighbors]] block, and shows the log line gobgpd writes:

nc -z -w 3 -s 127.0.0.1 10.255.255.1 179; sleep 1
sudo journalctl -u gobgpd --since "1 minute ago" -o cat | grep "Can't find configuration" | tail -1
Connection to 10.255.255.1 179 port [tcp/bgp] succeeded!
{"time":"2026-11-09T17:02:10.365502151Z","level":"INFO","msg":"Can't find configuration for a new passive connection","Topic":"Server","Key":"127.0.0.1"}

The TCP connection opens, but gobgpd sends no BGP OPEN and closes it, so the session never reaches Established. The same applies to any address on your network once you add your private IP to local-address-list: only the neighbors you configure can bring up a session.

The gRPC API is unauthenticated. Anyone who can connect to it controls this router, so on this image it is served only on the two Unix sockets above, owned by root:gobgp with mode 0660 in directories only the gobgp group can enter. The ubuntu user is not in that group, so the CLI is refused by the kernel without sudo and works with it:

sudo ls -ld /run/gobgp /run/gobgp/gobgpd.sock /run/gobgp-peer/gobgpd.sock
id -nG
gobgp global 2>&1 | grep -o 'connect: permission denied' || true
sudo gobgp global
drwxr-x--- 2 gobgp gobgp 60 Nov  9 16:58 /run/gobgp
srw-rw---- 1 root  gobgp  0 Nov  9 16:58 /run/gobgp-peer/gobgpd.sock
srw-rw---- 1 root  gobgp  0 Nov  9 16:58 /run/gobgp/gobgpd.sock
ubuntu adm cdrom sudo dip lxd
connect: permission denied
AS:        65001
Router-ID: 10.255.255.1
Listening Port: 179, Addresses: 10.255.255.1

Let an operator use gobgp without sudo

Add the operator's account to the gobgp group. The change applies at their next login:

sudo usermod -aG gobgp alice

Only add people you would trust with root on the router: a member of the gobgp group can change every neighbor, route and policy. Never expose the API on a TCP address with --api-hosts; if a remote controller must drive GoBGP, reach the socket over SSH instead.

Step 8: Metadata access is blocked for the daemons

Every GoBGP unit carries a systemd IPAddressDeny rule for the instance metadata addresses, so nothing running inside gobgpd can reach them. Each entry is a single address, so your peers and the Amazon Time Sync Service at 169.254.169.123 keep working, as chrony shows. Both daemons run as the unprivileged gobgp user, with the API socket and with pprof and metrics off on the command line:

systemctl show -p IPAddressDeny gobgpd.service gobgpd-peer.service
chronyc -n sources | grep 169.254
ps -o user,args -C gobgpd
IPAddressDeny=168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 ::ffff:169.254.169.254/128 ::ffff:168.63.129.16/128

IPAddressDeny=::ffff:168.63.129.16/128 ::ffff:169.254.169.254/128 169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
^* 169.254.169.123               3   4   377    22  -9297ns[-1894ns] +/-  525us
USER     COMMAND
gobgp    /usr/local/bin/gobgpd -f /etc/gobgp/gobgpd.conf -t toml -l info --api-hosts unix:///run/gobgp/gobgpd.sock --pprof-disable --metrics-path= --sdnotify
gobgp    /usr/local/bin/gobgpd -f /etc/gobgp/gobgpd-peer.conf -t toml -l info --api-hosts unix:///run/gobgp-peer/gobgpd.sock --pprof-disable --metrics-path= --sdnotify

--pprof-disable and the empty --metrics-path= are both needed: gobgpd opens its HTTP listener on localhost:6060 if either pprof or metrics is enabled.

Step 9: Peer with your own routers

The primary's configuration is /etc/gobgp/gobgpd.conf. First find this instance's private IP: BGP peers on your VPC connect to it, never to the public address. The metadata service needs an IMDSv2 token:

TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H 'X-aws-ec2-metadata-token-ttl-seconds: 60')
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/local-ipv4; echo
172.31.80.182

Then edit /etc/gobgp/gobgpd.conf with sudo and your editor. For a production router, replace the demo content (the AS number, router ID and local-address-list, the demo [[neighbors]] block, the blackhole prefix set and the reject-blackhole policy) with your own. A minimal edge configuration that peers with one router over TCP-MD5 and TTL security, and accepts only the prefixes you expect from it, looks like this:

[global.config]
  as = 64512
  router-id = "172.31.80.182"
  port = 179
  local-address-list = ["172.31.80.182"]

# Accept only the prefixes you expect; reject everything else (eBGP should never be accept-all).
[global.apply-policy.config]
  import-policy-list = ["from-core"]
  default-import-policy = "reject-route"

[[neighbors]]
  [neighbors.config]
    peer-as = 64513
    neighbor-address = "172.31.80.10"
    auth-password = "replace-with-the-key-you-agree-with-this-peer"
    description = "core-router-1"
  [neighbors.transport.config]
    local-address = "172.31.80.182"
  # GTSM (RFC 5082): accept BGP packets from this directly connected peer only if they arrive with TTL 255.
  [neighbors.ttl-security.config]
    enabled = true
    ttl-min = 255

[[defined-sets.prefix-sets]]
  prefix-set-name = "core-prefixes"
  [[defined-sets.prefix-sets.prefix-list]]
    ip-prefix = "10.20.0.0/16"
    masklength-range = "16..24"

[[policy-definitions]]
  name = "from-core"
  [[policy-definitions.statements]]
    name = "accept-core"
    [policy-definitions.statements.conditions.match-prefix-set]
      prefix-set = "core-prefixes"
    [policy-definitions.statements.actions]
      route-disposition = "accept-route"

Replace the AS numbers, addresses, prefixes and key with your own:

  • TCP-MD5 (auth-password) authenticates every packet of the session; the peer must be configured with the same key, and a session with a wrong or missing key never comes up.
  • TTL security (ttl-security) makes gobgpd send with TTL 255 and drop BGP packets that arrive with a lower TTL, so a spoofer more than one hop away cannot reach the session. Enable it on both ends, and only for directly connected peers. For a peer several hops away, leave it out and use [neighbors.ebgp-multihop.config] instead.

Check the file before you apply it, then restart the daemon:

sudo gobgpd --dry-run -f /etc/gobgp/gobgpd.conf -t toml --pprof-disable --metrics-path=
sudo systemctl restart gobgpd

gobgpd --dry-run exits without starting anything and logs Can't read config file with the reason when the file does not parse. If you restart with a configuration it rejects, gobgpd.service stops in the failed state and nothing listens until you fix the file. To announce your own prefixes at every start, list them one per line in /etc/gobgp/originate-gobgpd.txt (replacing 203.0.113.0/24). Once you no longer need the demo, stop the demo peer with sudo systemctl disable --now gobgpd-peer.service.

Step 10: Open BGP to your peers in the security group

Allow TCP 179 from your peers only in the instance's security group. In the EC2 console choose the instance, open Security, choose the security group, then Edit inbound rules:

Protocol Port Source Purpose
TCP 179 each peer's address (/32) BGP sessions

Add one rule per peer rather than a subnet-wide range: gobgpd refuses sessions from addresses it has no neighbor block for, and the security group keeps everyone else from reaching port 179 at all.

Two EC2 settings matter if this instance will forward traffic for the routes it learns rather than only exchange routes:

  • Disable the source/destination check on the instance's network interface (EC2 console: Actions, Networking, Change source/destination check). EC2 drops forwarded packets otherwise.
  • Point your VPC route tables at the instance for the prefixes it should carry, and enable IP forwarding on the instance (net.ipv4.ip_forward=1 in /etc/sysctl.d/).

GoBGP does not install the routes it learns into the kernel routing table by itself; it is a route server and route injector by default. To program the kernel, pair it with a FIB manager such as the zebra daemon from FRRouting, or have your own software read routes from the gRPC API.

You can also change the running daemon without editing the file, for example sudo gobgp neighbor add 172.31.80.10 as 64513 or sudo gobgp global rib add 198.18.0.0/24 -a ipv4. Changes made over the API last until the daemon restarts; put anything permanent in gobgpd.conf. gobgp --help and gobgp <command> --help list every command.

Step 11: Manage the service

systemctl status gobgpd --no-pager -n 0
sudo journalctl -u gobgpd -n 8 --no-pager -o cat
● gobgpd.service - GoBGP primary daemon AS 65001, gRPC unix:///run/gobgp/gobgpd.sock (cloudimg)
     Loaded: loaded (/etc/systemd/system/gobgpd.service; enabled; preset: enabled)
    Drop-In: /etc/systemd/system/gobgpd.service.d
             └─50-cloudimg-imds-deny.conf
     Active: active (running) since Mon 2026-11-09 16:58:31 UTC; 3min 39s ago
       Docs: https://www.cloudimg.co.uk/guides/gobgp-4-11-0-on-ubuntu-24-04-aws/
             https://github.com/osrg/gobgp
   Main PID: 4234 (gobgpd)
      Tasks: 8 (limit: 3736)
     Memory: 7.2M (peak: 10.7M)
        CPU: 306ms
     CGroup: /system.slice/gobgpd.service
             └─4234 /usr/local/bin/gobgpd -f /etc/gobgp/gobgpd.conf -t toml -l info --api-hosts unix:///run/gobgp/gobgpd.sock --pprof-disable --metrics-path= --sdnotify
gobgp-originate: 1 prefix(es) originated on /run/gobgp/gobgpd.sock
Started gobgpd.service - GoBGP primary daemon AS 65001, gRPC unix:///run/gobgp/gobgpd.sock (cloudimg).
{"time":"2026-11-09T16:58:31.683996579Z","level":"INFO","msg":"Peer Up","Topic":"Peer","Key":"10.255.255.2"}
{"time":"2026-11-09T16:58:44.098468823Z","level":"INFO","msg":"Peer Up","Topic":"Peer","Key":"10.255.255.2"}
{"time":"2026-11-09T17:02:10.365502151Z","level":"INFO","msg":"Can't find configuration for a new passive connection","Topic":"Server","Key":"127.0.0.1"}

gobgpd logs one JSON object per line: session state changes, updates and refused connections. The drop-in line confirms the metadata block is applied. Common commands:

sudo gobgp neighbor                              # every neighbor and its state
sudo gobgp neighbor <peer-ip> adj-in -a ipv4     # what a peer sent you, before policy
sudo gobgp neighbor <peer-ip> adj-out -a ipv4    # what you announce to it
sudo gobgp neighbor <peer-ip> softresetin        # re-apply import policy without dropping the session
sudo gobgp neighbor <peer-ip> reset              # reset one session

Step 12: Security recommendations

  • Keep the security group tight. Allow TCP 179 only from each peer's own address, and SSH only from your management address.
  • Authenticate every session. Give each neighbor its own TCP-MD5 key (auth-password), agreed with that peer, and enable TTL security for directly connected peers.
  • Filter explicitly. Accept only the prefixes you expect from each peer and announce only your own. Use default-import-policy = "reject-route" on a router with real peers.
  • Guard the API. The gRPC API has no authentication, so whoever can open its socket controls the router. Keep the gobgp group to trusted operators, never bind --api-hosts to a TCP address, and keep the socket permissions as shipped.
  • Keep the OS patched. Unattended security upgrades are on for the Ubuntu packages. GoBGP itself is the pinned upstream release binary, so updating it means a newer cloudimg version from the listing.

Support and licensing

GoBGP is developed by the osrg project and distributed under the Apache License 2.0. The licence text is in /usr/share/doc/gobgp/LICENSE, and the Go modules linked into the binaries, each with its licence, are listed in /usr/share/doc/gobgp/THIRD-PARTY-MODULES.txt. cloudimg provides the packaging, the reference deployment, the per-instance key, the secure defaults and 24/7 support.

cloudimg is not affiliated with or endorsed by the osrg project. GoBGP is a mark of its owner and is used here only to identify the software.

For help with deployment or configuration, email support@cloudimg.co.uk or visit cloudimg support.