Debian 13 Networking Tools on AWS User Guide
Overview
This guide covers launching and verifying the Debian 13 Networking Tools AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Debian listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. Every release and variant in the listing is described at /guides/debian-server-aws/.
This version is the standard cloudimg Debian 13 image with a named set of networking tools from Debian's own archive already installed. It is built for network engineers who would otherwise install the same tools by hand on every jump host or troubleshooting instance. It is not a router or a firewall appliance: nothing routes, filters or listens until you turn it on.
- 56 of Debian's own networking packages, preinstalled. Packet capture (
tcpdump,tshark,tcpflow), path and latency (mtr,traceroute,tracepath,tcptraceroute,httping), throughput (iperf3), DNS (dig,host,drill,dnstracer), addressing (ipcalc,ipcalc-ng,sipcalc,ipv6calc,ndisc6), interface and traffic monitors (iftop,nload,bmon,nethogs,iptraf-ng,ifstat,vnstat,ethstatus), packet filtering tools (nftables,iptables,ipset,ebtables,arptables,conntrack), tunnels (wireguard-tools,openvpn), routing suites (frr,bird2),lldpd,socat,netcat,whoisand more. Every one comes from Debian 13'smainarchive (no backports, no third-party repository), and every installed version and licence is listed on the image. - Every daemon masked. The 17 services those packages ship (FRR, BIRD, OpenVPN, WireGuard's
wg-quick, lldpd, conntrackd, vnstat, nftables, the iperf3 server and ifupdown's units) are stopped, disabled and masked, so nothing starts at boot and nothing listens except SSH. You turn on the ones you need (Step 8). - CIS Level 1 Server remediation, exactly as in the standard Debian 13 version: remediated with the OpenSCAP CIS Level 1 Server profile from SCAP Security Guide 0.1.82 (the
ssg-debian13content, CIS Debian Linux 13 Benchmark v1.0.0), rebooted and evaluated. On this build 359 of 363 scored rules pass (98.9%). Six rules are waived because they cannot work on an EC2 image, each with its reason. The report, the results, the waiver list and a summary ship in/usr/share/doc/cloudimg/. - EC2 defaults that keep you in control. Key-only SSH as
admin, root locked, no password on any account, X11 forwarding off, AppArmor enabled, IMDSv2 required, a host firewall (ufw) that allows SSH in and everything out, the AWS Systems Manager agent, and time from the Amazon Time Sync Service. - Fully patched at build time, with
unattended-upgradesinstalling Debian security updates on your instance.
What is on the image: everything in the standard Debian 13 version (the Debian cloud-amd64 kernel, cloud-init, OpenSSH, ufw, chrony, AppArmor, the AWS Systems Manager agent, rsyslog, AIDE, exim4 for local mail only, unattended-upgrades, the AWS CLI version 2 from Debian's archive, OpenSCAP and the pinned SCAP Security Guide content) plus the networking packages and their dependencies. The image has 495 installed packages.
Not included, on purpose: iptables-persistent and netfilter-persistent (ufw, this image's host firewall, declares that it breaks them), the telnet and LDAP command-line clients (the CIS Level 1 Server profile removes them), snmp, ngrep, fping and ssldump (their licences are not on cloudimg's open source licence allowlist), arping (it conflicts with iputils-arping, which is installed), and scanners or offensive tools such as nmap. The full list with each reason is in the manifest (Step 4).
Default user: admin · Architecture: x86_64 · Root volume: 8 GiB gp3, ext4 (grows to the size you choose at launch)
These images are remediated with an OpenSCAP profile and ship their own evaluation report. They are not CIS Hardened Images, and CIS has not reviewed or certified them.
Connecting to your instance
| Version | SSH user | Root device |
|---|---|---|
| Debian 13 Networking Tools | admin |
/dev/xvda (8 GiB gp3) |
Security posture
- No known credential. There is no default password and no baked in SSH key. The only key that works is the EC2 key pair you choose at launch, which cloud-init installs for
adminon first boot. - Key-only SSH.
PasswordAuthentication no,PermitRootLogin no, keyboard-interactive off, X11 forwarding off. The root account has no password and is locked. - Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance, so no two instances share a host key.
- IMDSv2 required. The AMI is registered with
ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests by default. - Nothing extra listens. Every service the networking packages ship is masked. Only
sshdlistens on a network address; the DNS stub resolver and the local mail service listen on loopback only. - Packet capture needs root.
dumpcap(used bytshark) has no setuid bit and no file capabilities, so capturing traffic requiressudo. - Host firewall. ufw denies inbound traffic except SSH and allows all outbound traffic.
Prerequisites
- An AWS account and permission to launch EC2 instances
- An EC2 key pair in the Region you launch in
- A security group that allows TCP 22 from your own address (not from the whole internet)
Recommended instance type: m5.large. The image runs on any current x86_64 instance type.
Step 1: Launch the instance
Option A: AWS Marketplace console
- Open the cloudimg Debian listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
- Once the subscription is active, choose Launch your software.
- Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for full control), then in Version choose Debian 13 Networking Tools - YYYY-MM-DD (the date is when the version was added) and your Region.
- Instance type:
m5.largeis recommended; any current x86_64 type works. The software charge is $0.04 per vCPU per hour. - Key pair: choose your EC2 key pair. It is the only way in. RSA and ED25519 keys both work.
- Security group: allow inbound TCP 22 from your own IP address or network only.
- Storage: the root volume is 8 GiB gp3 by default. Choose a larger size if you keep packet captures on the instance; cloud-init grows the root partition and filesystem to fill it on first boot.
- Metadata: leave the defaults. The image already requires IMDSv2. Then choose Launch.
Option B: AWS CLI
Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the key pair, security group and subnet with your own. The root device of this AMI is /dev/xvda:
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key-pair \
--security-group-ids sg-0123456789abcdef0 \
--subnet-id subnet-0123456789abcdef0 \
--block-device-mappings 'DeviceName=/dev/xvda,Ebs={VolumeSize=20,VolumeType=gp3}' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=debian-13-networking-tools}]'
You do not need --metadata-options: the AMI already makes IMDSv2 required.
Step 2: Connect via SSH
From your workstation, connect as admin with the key pair you chose:
ssh -i ~/.ssh/my-key-pair.pem admin@<public-ip>
There is no password to enter. If SSH asks for one, or says Too many authentication failures, see Troubleshooting below.
You can also connect without opening port 22 at all through AWS Systems Manager Session Manager, if the instance has an instance profile that allows Systems Manager. The agent is installed and running on this image.
Step 3: Confirm the release
cat /etc/debian_version
grep -E '^(PRETTY_NAME|VERSION_ID|VERSION_CODENAME|ID)=' /etc/os-release
uname -srm
dpkg-query -W -f='${db:Status-Abbrev}\n' | grep -c '^ii'
Expected output:
13.7
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
VERSION_ID="13"
VERSION_CODENAME=trixie
ID=debian
Linux 6.12.113+deb13-cloud-amd64 x86_64
495

This version follows Debian 13: it receives every Debian 13 point release (13.7 at build time) through normal apt updates. Your kernel version may be newer if updates have installed since this image was built. The package count moves by a few as kernels and updates install, and by one more if your account runs Amazon Inspector, whose Systems Manager association installs its own inspectorssmplugin package.
Step 4: Read the networking manifest
The image describes its own networking set. The manifest was written from the package database when the image was built:
grep -vc '^#' /usr/share/doc/cloudimg/pkgprofile-networking-manifest.txt
grep -v '^#' /usr/share/doc/cloudimg/pkgprofile-networking-manifest.txt | head -6
Expected output (each line is package, version at build time, licence, licence verdict):
56
iproute2 6.15.0-1 GPL-2.0-only allow
net-tools 2.10-1.3 GPL-2.0-or-later allow
tcpdump 4.99.5-2 BSD-3-Clause allow
traceroute 1:2.1.6-1 GPL-2.0-or-later allow
mtr-tiny 0.95-1.1+b1 GPL-2.0-or-later allow
iperf3 3.18-2+deb13u2 BSD-3-Clause-LBNL allow
- The versions are the ones installed when the image was built;
aptupdates them like any other package (dpkg -l <package>shows what is installed now). curlis markedbase-image: it is part of every Debian image already, and its licence (the curl licence) is listed as it is.- The manifest also lists the excluded packages with their reasons, the 17 masked services, and every dependency the networking set pulled in (117 packages in total). Read it all with
less /usr/share/doc/cloudimg/pkgprofile-networking-manifest.txt.
Each package's full licence text is in /usr/share/doc/<package>/copyright.
Step 5: Read the compliance evidence
The evaluation the build ran after its reboot ships on the image, as in the standard Debian 13 version:
python3 -c "import json; s=json.load(open('/usr/share/doc/cloudimg/cis-l1-summary.json')); print('profile: ', s['profileLabel'], '(SCAP Security Guide', s['ssgVersion'] + ')'); print('scored rules: ', s['scored'], ' pass:', s['pass'], ' fail:', s['fail'], '(+%d error)' % s['error'], ' rate:', str(s['ratePct']) + '%'); print('waived: ', s['waived'], ' not applicable:', s['notapplicable'])"
python3 -c "import json; [print(r) for r in json.load(open('/usr/share/doc/cloudimg/cis-l1-summary.json'))['failingRules']]"
Expected output:
profile: CIS Level 1 Server (SCAP Security Guide 0.1.82)
scored rules: 363 pass: 359 fail: 3 (+1 error) rate: 98.9%
waived: 6 not applicable: 33
file_ownerships_var_log
journald_forward_to_syslog
service_systemd-journal-upload_enabled
systemd_journal_upload_url

The HTML report (cis-l1-report.html), the machine-readable results (cis-l1-arf.xml), the tailoring (cis-l1-tailoring.xml) and the six waived rules with their reasons (cis-l1-waivers.txt) are in /usr/share/doc/cloudimg/. The Debian 13 guide explains each waiver.
The four rules that do not pass stay in the score rather than being hidden:
- journald forwarding and the remote journal upload (
journald_forward_to_syslog,service_systemd-journal-upload_enabled,systemd_journal_upload_url) are the same three as in the standard Debian 13 version: the profile asks for both journal forwarding settings at once, and the image cannot know your log collector. To send the journal to yours, setURL=in/etc/systemd/journal-upload.conf, then runsudo systemctl enable --now systemd-journal-upload. - Log file ownership (
file_ownerships_var_log) reportserror, notfail. The check accepts only files owned byrootor asyslogaccount, and Debian has nosyslogaccount. The one file it trips on is/var/log/aide/aide.log, which belongs to the_aideaccount on purpose: Debian's daily AIDE check runs as_aideand has to rotate its own log. If that file belonged to root, the daily check would fail every day and the instance would report a failed service.
To re-run the evaluation yourself (about a minute):
sudo oscap xccdf eval \
--tailoring-file /usr/share/doc/cloudimg/cis-l1-tailoring.xml \
--profile xccdf_co.cloudimg_profile_cis-l1_ec2_single \
--results /tmp/cis-check-results.xml --report /tmp/cis-check-report.html \
/usr/share/xml/scap/ssg/content/ssg-debian13-ds.xml > /tmp/cis-check.log 2>&1
echo "oscap exit code: $? (2 = at least one rule did not pass)"
sudo python3 -c "import re,collections; c=collections.Counter(re.findall(r'<result>(\w+)</result>', open('/tmp/cis-check-results.xml').read())); s=sum(c[k] for k in ('pass','fail','error','unknown')); print(dict(sorted(c.items()))); print('pass rate: %.1f%%' % (100.0*c['pass']/s))"
Expected output:
oscap exit code: 2 (2 = at least one rule did not pass)
{'error': 1, 'fail': 4, 'notapplicable': 33, 'notchecked': 1, 'notselected': 380, 'pass': 358}
pass rate: 98.6%
A running instance scores one rule lower than the shipped evaluation (file_permissions_backup_etc_shadow): on first boot cloud-init locks the admin password and the system writes a new /etc/shadow- backup at mode 0640. sudo chmod 0000 /etc/shadow- makes the rule pass again. The Debian 13 guide explains it in full.
Step 6: Confirm IMDSv2 is required
curl -s -o /dev/null -w 'IMDSv1 request without a token: HTTP %{http_code}\n' http://169.254.169.254/latest/meta-data/instance-id
TOKEN=$(curl -s -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' http://169.254.169.254/latest/api/token)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" -w '\n' http://169.254.169.254/latest/meta-data/placement/region
Expected output (your Region may differ):
IMDSv1 request without a token: HTTP 401
us-east-1
Step 7: The host firewall, listening ports and masked services
sudo ufw status verbose
sudo ss -tlnp
systemctl is-enabled frr.service bird.service openvpn.service wg-quick@.service lldpd.service vnstat.service nftables.service || true
Expected output (process IDs vary):
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
Anywhere on lo ALLOW IN Anywhere
22/tcp ALLOW IN Anywhere
68/udp ALLOW IN 67/udp # DHCP client: replies from a DHCP server (port 67)
53 on lo ALLOW IN Anywhere # systemd-resolved loopback stub 127.0.0.54:53 (lo only)
Anywhere (v6) on lo ALLOW IN Anywhere (v6)
22/tcp (v6) ALLOW IN Anywhere (v6)
53 (v6) on lo ALLOW IN Anywhere (v6) # systemd-resolved loopback stub 127.0.0.54:53 (lo only)
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=852,fd=6))
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=336,fd=17))
LISTEN 0 20 127.0.0.1:25 0.0.0.0:* users:(("exim4",pid=1452,fd=5))
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=336,fd=15))
LISTEN 0 20 [::1]:25 [::]:* users:(("exim4",pid=1452,fd=6))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=852,fd=7))
masked
masked
masked
masked
masked
masked
masked

- Only
sshdlistens on a network address, on port 22. The DNS stub resolver (127.0.0.53 and 127.0.0.54) and the local mail service (exim4, port 25) listen on loopback only, exactly as on the standard Debian 13 version. maskedmeans the service cannot be started, by hand, at boot or by a package update, until you unmask it (Step 8). The full list is in the manifest.- ufw and the packet filtering tools. ufw is the host firewall and drives the kernel's packet filter through
iptables(the nftables backend), sosudo nft list rulesetandsudo iptables -Sshow ufw's chains. Use them to inspect; make changes withufw. If you would rather manage the firewall with your own nftables ruleset, disable ufw first (sudo ufw disable), then unmask and enablenftables.service. Never run both. - Opening a port for your own service takes two steps: allow it in the instance's security group, and allow it in ufw (for example
sudo ufw allow 179/tcpfor BGP).
Step 8: Turn a service on when you want it
Nothing starts by itself. To run one of the masked services, unmask it, enable it, then open its port in the security group and ufw. For example, LLDP neighbour discovery:
sudo systemctl unmask lldpd.service
sudo systemctl enable --now lldpd.service
sudo lldpcli show neighbors
The other services follow the same pattern: frr.service (configure the daemons in /etc/frr/daemons first), bird.service (/etc/bird/bird.conf), openvpn-server@<name>.service or openvpn-client@<name>.service (with /etc/openvpn/server/<name>.conf or /etc/openvpn/client/<name>.conf), wg-quick@<interface>.service (with /etc/wireguard/<interface>.conf), vnstat.service, conntrackd.service and iperf3.service. To put one back the way it shipped:
sudo systemctl disable --now lldpd.service
sudo systemctl mask lldpd.service
Three things to know before you route or tunnel traffic through the instance:
- IP forwarding is off. The CIS profile turns it off in
/etc/sysctl.conf(net.ipv4.conf.all.forwarding = 0,net.ipv6.conf.all.forwarding = 0and theirdefaultcounterparts). A router or VPN gateway needs it on, a deliberate departure from the benchmark: change the IPv4 line to1in/etc/sysctl.conf, uncommentnet/ipv4/ip_forward=1in/etc/ufw/sysctl.conf(ufw applies that file when it starts), do the same for the IPv6 lines if you route IPv6, then runsudo sysctl --system && sudo ufw reload./usr/sbin/sysctl net.ipv4.ip_forwardthen reports1, and it stays on after a reboot. - ufw blocks routed traffic (
disabled (routed)). Allow what you route withsudo ufw route allow .... - EC2 drops traffic that is not addressed to the instance unless you turn off source/destination check on its network interface (EC2 console, Networking, Change source/destination check). Routing and VPN gateway instances need it off.
Step 9: Use the toolbox
Everything below runs as shipped, with no service to start.
Interfaces and addresses:
ip -brief address show
Expected output (your addresses will differ):
lo UNKNOWN 127.0.0.1/8 ::1/128
ens5 UP 172.31.89.177/20 metric 100 fe80::10ff:ceff:fec9:ef13/64
Capture traffic (capture needs sudo). This starts a capture of ICMP on the instance's network interface, then sends two pings so there is something to see:
(sudo timeout 20 tcpdump -i ens5 -c 4 -n -q icmp 2>&1 &); sleep 2; ping -c 2 -q 1.1.1.1 >/dev/null; sleep 2
Expected output (your address and the timings will differ):
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens5, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:10:41.816124 IP 172.31.89.177 > 1.1.1.1: ICMP echo request, id 1, seq 1, length 64
21:10:41.817042 IP 1.1.1.1 > 172.31.89.177: ICMP echo reply, id 1, seq 1, length 64
21:10:42.817182 IP 172.31.89.177 > 1.1.1.1: ICMP echo request, id 1, seq 2, length 64
21:10:42.818098 IP 1.1.1.1 > 172.31.89.177: ICMP echo reply, id 1, seq 2, length 64
4 packets captured
4 packets received by filter
0 packets dropped by kernel
On a Nitro instance the network interface is ens5 (ip -brief address show lists it). tshark -i ens5 captures the same way with Wireshark's decoders.
Query DNS with BIND's dig or ldns's drill:
dig +short A www.cloudimg.co.uk | head -3
drill -Q debian.org NS | head -3
Expected output (the answers change over time):
d14bmdyrx9dte8.cloudfront.net.
3.167.88.51
3.167.88.56
dns4.easydns.info.
sec1.rcode0.net.
sec2.rcode0.net.
Trace a path:
mtr -n -r -c 2 -m 4 1.1.1.1
Expected output (hops and timings depend on your Region and network):
Start: 2026-10-24T20:55:07+0000
HOST: ip-172-31-89-177 Loss% Snt Last Avg Best Wrst StDev
1.|-- 244.5.8.69 0.0% 2 7.1 4.8 2.4 7.1 3.3
2.|-- 240.0.60.131 0.0% 2 0.5 0.5 0.5 0.5 0.0
3.|-- 242.1.11.87 0.0% 2 1.0 1.2 1.0 1.4 0.3
4.|-- 52.46.166.112 0.0% 2 1.6 1.8 1.6 2.0 0.3
Measure throughput. iperf3 needs a server at the far end; you can prove the tool works against the instance's own loopback first. The -1 flag makes the server exit after one test, so nothing is left listening:
(iperf3 -s -1 -p 5399 -B 127.0.0.1 >/dev/null 2>&1 &) ; sleep 1; iperf3 -c 127.0.0.1 -p 5399 -t 1 -f m | tail -4
Expected output (the rate depends on your instance type):
[ 5] 0.00-1.00 sec 3.44 GBytes 29539 Mbits/sec 0 sender
[ 5] 0.00-1.00 sec 3.44 GBytes 29537 Mbits/sec receiver
iperf Done.
To test between two instances, run iperf3 -s on one (allow TCP 5201 from the other in both the security group and ufw) and iperf3 -c <its private IP> on the other.
Plan addresses:
ipcalc-ng 10.20.0.0/22 | head -8
Expected output:
Network: 10.20.0.0/22
Netmask: 255.255.252.0 = 22
Broadcast: 10.20.3.255
Address space: Private Use
HostMin: 10.20.0.1
HostMax: 10.20.3.254
Hosts/Net: 1022
Tool versions. Several of the routing and tunnel tools live in /usr/sbin:
dpkg-query -W -f='${Package} ${Version}\n' frr tshark wireguard-tools iperf3 bind9-dnsutils
/usr/sbin/openvpn --version | head -1
/usr/sbin/bird --version 2>&1 | head -1
Expected output (the versions move forward with Debian security updates):
frr 10.3-3+deb13u1
tshark 4.4.19-0+deb13u1
wireguard-tools 1.0.20210914-3
iperf3 3.18-2+deb13u2
bind9-dnsutils 1:9.20.30-1~deb13u1
OpenVPN 2.6.14 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]
BIRD version 2.17.5

Step 10: Patch level, support status and automatic updates
The image is fully patched at build time. Check what is pending now and how long Debian supports what is installed:
sudo apt-get update -qq
apt list --upgradable 2>/dev/null
cat /etc/apt/apt.conf.d/20auto-upgrades
check-support-status --no-heading
Expected output on an instance launched soon after the image was built (later launches list the updates released since):
Listing...
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
* Source:rust-rpm-sequoia
Details: See https://www.debian.org/releases/trixie/release-notes/issues.en.html#go-and-rust-based-packages
Affected binary package:
- librpm-sequoia-1:amd64 (installed version: 1.8.0-2)
check-support-status (from Debian's debian-security-support package, installed for this purpose) lists installed packages whose security support is limited or ended. None of the networking packages is listed. The one entry is librpm-sequoia-1, a Rust-based library that OpenSCAP's scanner depends on (it is on every cloudimg Debian 13 version); Debian's release notes explain that Go and Rust based packages get security updates on a best-effort basis.
unattended-upgrades runs daily and installs updates from the Debian and Debian-Security archives automatically, the networking packages included. To update everything now, run sudo apt-get update && sudo apt-get -y upgrade, and reboot if a new kernel was installed.
Step 11: Security settings, time and file integrity
sudo passwd -S root
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|x11forwarding|maxauthtries) '
stat -c '%a %U:%G %n' /usr/bin/dumpcap
chronyc -n sources | grep '^\^\*'
systemctl is-enabled aidecheck.timer
systemctl is-system-running
Expected output (the time source timings vary):
root L 2026-10-21 0 99999 7 -1
maxauthtries 4
permitrootlogin no
passwordauthentication no
x11forwarding no
755 root:root /usr/bin/dumpcap
^* 169.254.169.123 3 4 377 6 +16us[ +16us] +/- 490us
enabled
running
Lmeans the root account is locked; SSH is key-only (pinned in/etc/ssh/sshd_config.d/00-ec2-key-only.conf).dumpcapis mode755with no setuid bit and no file capabilities, so only root can capture. To let a group capture withoutsudo, runsudo dpkg-reconfigure wireshark-common, answer yes, and add the account to thewiresharkgroup.- chrony uses the Amazon Time Sync Service (
169.254.169.123), which works in a private subnet. - AIDE checks file integrity at boot and daily (
aidecheck.timer; results injournalctl -u aidecheck). After you install or change software, refresh its database:sudo aide --config /etc/aide/aide.conf --init, thensudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db. runningmeans no service failed during boot.
EC2 Serial Console. No account on this image has a password, so the serial console cannot log in until you set one for your own user (sudo passwd admin).
Common use cases
- A ready jump host or bastion for troubleshooting a VPC: capture, trace, resolve and measure without installing anything first
- Throughput and latency testing between Availability Zones, Regions or on-premises sites with
iperf3,mtrandhttping - A starting point for a WireGuard or OpenVPN endpoint, or a BGP or OSPF speaker with FRR or BIRD, once you have turned on forwarding and the service you need
- DNS diagnostics with two independent clients (
diganddrill) plusdnstracer - A Debian 13 base for network automation that must show CIS Level 1 alignment, with the report already on the machine
Troubleshooting
SSH says "Too many authentication failures"
The SSH server allows four authentication attempts per connection. Tell SSH to offer only the key you name:
ssh -o IdentitiesOnly=yes -i ~/.ssh/my-key-pair.pem admin@<public-ip>
Cannot connect via SSH
- Check the instance is running and has passed its status checks.
- Check the security group allows TCP 22 from your current public address.
- Use the user name
adminand the key pair chosen at launch. Password login is disabled. - If you changed ufw, make sure 22/tcp is still allowed (
sudo ufw allow 22/tcp). Session Manager still works if SSH is blocked, provided the instance has a Systems Manager instance profile.
A service will not start: "Unit ... is masked"
The networking services ship masked. Unmask the service first, then enable it (Step 8).
openvpn, bird or sysctl says "command not found"
These programs are in /usr/sbin, which is on root's path but not on the admin user's. Run them with sudo or with their full path, for example /usr/sbin/openvpn --version. FRR's shell, vtysh, is in /usr/bin and needs sudo and a running frr.service.
traceroute or mtr shows ??? for some hops
Many routers on the path, including parts of the AWS network, do not answer the probes. That is normal and does not mean the path is broken.
My routed or tunnelled traffic does not arrive
Check the three things in Step 8: IP forwarding on, ufw route rules, and the EC2 source/destination check off.
Running the daily AIDE check by hand a second time fails
Debian's dailyaidecheck.service (run once a day by dailyaidecheck.timer) allows one start every two hours, and its cache helper dailyaidecheck-buildcache.service one a minute. A second sudo systemctl start dailyaidecheck.service inside that window is refused (start-limit-hit or A dependency job for dailyaidecheck.service failed), and systemctl is-system-running then reports degraded. Nothing is wrong with AIDE: wait, then clear the record with sudo systemctl reset-failed, which returns the state to running.
Package manager issues
Refresh the package lists first (sudo apt-get update). If the archive is unreachable, check that the instance has outbound internet access (a public IP or a NAT gateway) and that DNS resolves (getent hosts deb.debian.org).
Important notes
Debian is free and open source software. It is a distribution of thousands of packages, each under its own licence (GPL, LGPL, MIT, BSD, Apache 2.0 and others); /usr/share/doc/<package>/copyright shows each package's licence, and the networking manifest (Step 4) lists the licence of each networking package. No subscription or licence key is needed to run this image. The compliance tooling is OpenSCAP (LGPL 2.1 or later) and SCAP Security Guide content (BSD 3-Clause).
Debian 13 is Debian's current stable release and receives security updates from the Debian Security Team through the trixie-security archive this image already uses.
The CIS Level 1 Server profile used here is the OpenSCAP profile published in SCAP Security Guide. These images are not CIS Hardened Images and are not certified by the Center for Internet Security. A pass rate measures this image as built; your own changes affect it (turning on forwarding for a router, for example), which is why the evaluation can be re-run (Step 5).
Debian is a registered trademark of Software in the Public Interest, Inc. CIS is a trademark of the Center for Internet Security. Wireshark is a registered trademark of the Wireshark Foundation. These names are used only to identify the software and the profile. cloudimg is not affiliated with or endorsed by the Debian Project, Software in the Public Interest, the Center for Internet Security or the Wireshark Foundation.
Support
For help with this image, contact cloudimg support:
- Website: www.cloudimg.co.uk
- User Guides: www.cloudimg.co.uk/guides
- Debian on AWS hub: www.cloudimg.co.uk/guides/debian-server-aws