TTR Networks

Intermediate · Setting up VyOS with basic BGP · section 7 of 9

Locking down management

✓ Lab-tested 17 October 2026 on VyOS 2026.10.16-0024-rolling, FRR 10.2.1

R1 now routes correctly, but anyone who can reach it can talk to it. Out of the box, this VyOS build doesn't run SSH at all, yet BGP's TCP port 179 answers connections from any address, including your LAN and the whole internet. (BGP itself rejects strangers, but only after the TCP handshake, so the port is still a target.) Before a router goes into production, lock down how it's managed.

A management address

Give the router one address that exists only for management, and bind every management service to it. A loopback is ideal: it's always up, it doesn't belong to any one link, and its purpose is obvious. Here R1 gets 198.51.100.254/32, from the unused half of the /24. (It's more specific than the blackhole, so it still works.)

In a bigger network, management usually lives on a separate out-of-band network or in its own Virtual Routing and Forwarding (VRF) instance, so you can still reach the router when the production network is broken. The idea is the same: one known address per router, and services listen nowhere else.

SSH: keys only, on that address

  • listen-address binds SSH to the management loopback. Connections to any other address on the router are refused outright.
  • Log in with SSH keys. Load your public key into the user account, check that key login works, then disable password authentication. Doing it in one commit, as here, is fine, but only if the key is right. On a remote router, use commit-confirm (see the checklist) so a mistake rolls itself back.
  • A pre-login banner states that access is restricted. It doesn't stop anyone, but it makes the terms of access explicit, which can matter if you ever need to take action against an intruder.
  • In production, give each person their own user with their own key, rather than sharing the vyos account.

An input firewall

Binding SSH to the loopback doesn't hide it: the loopback is inside our announced /24, so the whole internet can route to it. The lab proves it: before the firewall, the upstream could open a connection to SSH.

VyOS's firewall ipv4 input filter applies to traffic addressed to the router itself. It doesn't affect traffic passing through. A minimal policy:

  1. Accept replies to connections the router opened (established, related), and drop invalid packets.
  2. Accept anything from the router to itself (lo).
  3. Accept ICMP, so ping and path MTU discovery keep working.
  4. Accept SSH only from the management networks, and BGP only from configured neighbors.
  5. Drop everything else.

Firewall groups keep the rules readable, and mean that adding a BGP neighbor or a management subnet is a one-line change. Remember to add each new BGP neighbor to BGP-PEERS, or its session will never come up.

This lab only filters IPv4. If your interfaces have IPv6 addresses, write the same policy under firewall ipv6 input filter, because the IPv4 rules don't apply to IPv6 at all.

Also worth doing

  • NTP: VyOS ships with time1–3.vyos.net as NTP servers. Point it at your own or your provider's, so logs from every device line up.
  • Remote syslog, so you still have the logs if the router dies or is compromised.
  • SNMP or streaming telemetry for monitoring, bound to the management address and limited to your monitoring hosts, like SSH.
Stage 5: management address and SSH
set interfaces loopback lo address '198.51.100.254/32'
set system login banner pre-login 'Authorised access only. All activity is logged.'
set system login user vyos authentication public-keys admin@host key 'AAAAC3NzaC1lZDI1NTE5AAAAICr2rfW95lj3ygmOijRVlMJmROyeBWv+unBUvXjxfL6Y'
set system login user vyos authentication public-keys admin@host type 'ssh-ed25519'
set service ssh listen-address '198.51.100.254'
set service ssh disable-password-authentication
  • Line 1: The management loopback. A /32 inside our aggregate, so it's reachable from anywhere we route to.
  • Line 2: Shown before the password or key exchange completes.
  • Lines 3–4: The admin's public key (from ssh-keygen on the management host; the private key never leaves it).
  • Line 5: SSH listens on the management address only.
  • Line 6: Keys only. Commit this only once you know the key works, or use commit-confirm.
Stage 6: the input firewall
set firewall group network-group MGMT-NETS network '198.51.100.0/25'
set firewall group address-group BGP-PEERS address '203.0.113.0'
set firewall group address-group BGP-PEERS address '192.0.2.1'
set firewall ipv4 input filter default-action 'drop'
set firewall ipv4 input filter rule 10 action 'accept'
set firewall ipv4 input filter rule 10 state 'established'
set firewall ipv4 input filter rule 10 state 'related'
set firewall ipv4 input filter rule 20 action 'drop'
set firewall ipv4 input filter rule 20 state 'invalid'
set firewall ipv4 input filter rule 30 action 'accept'
set firewall ipv4 input filter rule 30 inbound-interface name 'lo'
set firewall ipv4 input filter rule 40 action 'accept'
set firewall ipv4 input filter rule 40 protocol 'icmp'
set firewall ipv4 input filter rule 50 action 'accept'
set firewall ipv4 input filter rule 50 protocol 'tcp'
set firewall ipv4 input filter rule 50 destination port '22'
set firewall ipv4 input filter rule 50 source group network-group 'MGMT-NETS'
set firewall ipv4 input filter rule 60 action 'accept'
set firewall ipv4 input filter rule 60 protocol 'tcp'
set firewall ipv4 input filter rule 60 destination port '179'
set firewall ipv4 input filter rule 60 source group address-group 'BGP-PEERS'
  • Lines 1–3: Groups: who may manage the router, and who may speak BGP to it.
  • Line 4: Anything not explicitly allowed, to the router itself, is dropped.
  • Lines 5–9: Replies to connections R1 opened (including BGP sessions it initiated), and junk that matches no connection.
  • Lines 10–11: The router talking to itself.
  • Lines 12–13: ICMP, so ping and path MTU discovery work.
  • Lines 14–17: SSH from the management networks only.
  • Lines 18–21: BGP from configured neighbors only.
SSH from the LAN host (real output)
root@host:~# ssh vyos@198.51.100.254 uname -n
Authorised access only. All activity is logged.
R1
root@host:~# ssh vyos@198.51.100.1 uname -n
ssh: connect to host 198.51.100.1 port 22: Connection refused
root@host:~# ssh -o PubkeyAuthentication=no vyos@198.51.100.254 uname -n
Authorised access only. All activity is logged.
vyos@198.51.100.254: Permission denied (publickey).
root@host:~# nc -zv -w3 198.51.100.1 179
nc: connect to 198.51.100.1 port 179 (tcp) timed out: Operation now in progress
  • Lines 1–3: Key login to the management address works, after the banner.
  • Lines 4–5: Nothing listens on the LAN address, so the router refuses the connection.
  • Lines 6–8: Without a key, the server only offers publickey: no password prompt to brute-force.
  • Lines 9–10: The LAN host isn't a BGP neighbor, so TCP 179 is silently dropped.
From the upstream, before and after (real output)
# Before the input firewall (management stage only)
upstream:/# nc -zv -w3 198.51.100.254 22
198.51.100.254 (198.51.100.254:22) open
upstream:/# nc -zv -w3 203.0.113.1 179
203.0.113.1 (203.0.113.1:179) open
# After the input firewall
upstream:/# nc -zv -w3 198.51.100.254 22
nc: 198.51.100.254 (198.51.100.254:22): Operation timed out
upstream:/# nc -zv -w3 203.0.113.1 179
203.0.113.1 (203.0.113.1:179) open
  • Lines 2–3: Before the firewall, the upstream (standing in for the internet) could reach SSH on the management address.
  • Lines 7–8: After: dropped, so the connection times out.
  • Lines 9–10: BGP from a configured neighbor still gets through.
Sessions and firewall counters (real output)
vyos@R1:~$ show ip bgp summary

IPv4 Unicast Summary:
BGP router identifier 198.51.100.1, local AS number 64500 VRF default vrf-id 0
BGP table version 12
RIB entries 5, using 800 bytes of memory
Peers 2, using 60 KiB of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
192.0.2.1       4      64511         8         7       12    0    0 00:03:20            1        1 IX route server 1
203.0.113.0     4      64496         9         7       12    0    0 00:03:39            2        1 UPSTREAM transit

Total number of neighbors 2
vyos@R1:~$ show firewall ipv4 input filter
Ruleset Information

---------------------------------
ipv4 Firewall "input filter"

Rule     Action    Protocol      Packets    Bytes  Conditions
-------  --------  ----------  ---------  -------  -------------------------------------------
10       accept    all                29     5864  ct state { established, related }  accept
20       drop      all                 0        0  ct state invalid
30       accept    all                 2      144  iifname "lo"  accept
40       accept    icmp                0        0  meta l4proto icmp  accept
50       accept    tcp                 1       60  tcp dport 22 ip saddr @N_MGMT-NETS  accept
60       accept    tcp                 1       60  tcp dport 179 ip saddr @A_BGP-PEERS  accept
default  drop      all                 6      360  comment "INP-filter default-action "
  • Lines 10–11: Both sessions stayed up through the firewall commit.
  • Line 22: Most traffic is matched here: the established BGP sessions.
  • Line 26: The host's SSH connection…
  • Line 27: …and the upstream's test connection to port 179.
  • Line 28: Everything else, including the upstream's SSH attempt and the host's port 179 test.

Check your understanding

SSH is bound to 198.51.100.254. Why is an input firewall still needed?

  • It isn't; binding hides SSH from the internet
  • Because the management address is routable from the internet, so binding alone doesn't restrict who can connect
  • To stop traffic passing through R1 to the LAN
  • Because SSH keys don't work without a firewall