Skip to content

Instantly share code, notes, and snippets.

@pinkeen
Last active May 4, 2024 18:08
Show Gist options
  • Save pinkeen/3076cd6f5cc5b08d3faacfa2db149a17 to your computer and use it in GitHub Desktop.
Save pinkeen/3076cd6f5cc5b08d3faacfa2db149a17 to your computer and use it in GitHub Desktop.
ER-X Configuration Cheat Sheet / Snippets

Ubiquity EdgeRouter - Personal Cheat Sheet and Improvements

Topics

Scripts

Improve your shell experience

Shell Screenshot

This script will set up:

  • coloured prompt with:
    • vyatta configuration edit session info (changed, saved, ...)
    • different colours for root / normal user
  • command aliases (which probably mostly I use)
  • command history with:
    • completion search (up/down arrow keys)
    • jump between words (left/right arrow keys + option/alt)

Install vhk.sh to /etc/profile.d:

curl -L https://gist.githubusercontent.com/pinkeen/3076cd6f5cc5b08d3faacfa2db149a17/raw/vhk.sh -o /etc/profile.d/99-custom.sh

For root profile is not sourced automatically so add:

echo '. /etc/profile' >> /root/.bashrc

Basic configuration hints

Keep last 10 configuration commit revisions (by default none is kept)

See the official docs for verbose info.

set system config-management commit-revisions 10

This allows you later list commits and roll them back.

After fuckup rollback to specficic revision

rollback ? # list commits
rollback {NUM}

Back config after commit via SSH/SCP

Note: I was not able to get it work key auth, only password seems possible.

set system config-management commit-archive location scp://user:pass@host.local/Some/Path/To/Backups

Enable dnsmasq for DHCP

Based on official Ubiquity Docs.

Just enable it: 😎

set service dhcp-server use-dnsmasq enable 
set service dhcp-server shared-network-name LAN1 subnet 192.168.1.0/24 domain-name ubnt.local

Install tools from Debian repository

1. Free up space

Remove the old system image left from previous update.

As root, but NOT in configuration mode:

delete system image

2. Install apt repo

Warning: This repos (stretch) work only for firmware 2.x

set system package repository stretch components 'main contrib non-free' 
set system package repository stretch distribution stretch
set system package repository stretch url http://http.us.debian.org/debian

2. Install the packages you want

apt -y install nano ccze htop dnsutils

3. ... and free-up space taken by apt

This will remove package index and the downloaded package files.

rm -rvf /var/lib/apt/lists/ /var/cache/apt/archives/

Restart Crashed / Hanging Web GUI

1. Kill lighttpd process manually beforehand, because otherwise the delete cmd hangs

pkill -9 -f lighttpd

2. Delete and re-add the GUI service

configure
delete service gui
commit
set service gui
commit

Setup PPTP VPN Client

Note: PPTP has been cracked and is considered insecure...

1. Create PPTP client iface

set interfaces pptp-client pptpc0
set interfaces pptp-client pptpc0 default-route auto
set interfaces pptp-client pptpc0 server-ip {remote-host}
set interfaces pptp-client pptpc0 description {label}
set interfaces pptp-client pptpc0 user-id {username}
set interfaces pptp-client pptpc0 password {password}

2. Add static PPTP route

set protocols static interface-route {target-subnet} next-hop-interface pptpc0

3. Set up a masquerade NAT Rule

set service nat rule 5005 outbound-interface pptpc0
set service nat rule 5005 type masquerade
set service nat rule 5005 description {rule-name}

[Maintenace] Restart the PPTP connections

If you need to restart a misbehaving PPTP connection without changing configuration you might use this trick.

configure
save
delete interfaces pptp-client
commit
load
compare
commit
exit

Auto-route traffic for AWS region to a VPN

My use-case: Our AWS SGs allow SSH access only from company network.

Install the route-aws-region-to-interface.sh script and execute it as task every 7 days to update routing.

curl -L https://gist.githubusercontent.com/pinkeen/3076cd6f5cc5b08d3faacfa2db149a17/raw/route-aws-region-to-interface.sh -o /config/scripts/route-aws-region-to-interface.sh
chmod +x /config/scripts/route-aws-region-to-interface.sh
set system task-scheduler task RouteAWSREgionEUCentral1ToPPTPC0 executable path /config/scripts/route-aws-region-to-interface.sh
set system task-scheduler task RouteAWSREgionEUCentral1ToPPTPC0 executable arguments 'eu-central-1 pptpc0'
set system task-scheduler task RouteAWSREgionEUCentral1ToPPTPC0 interval 7d

TODO: Improve the script

The static routes cannot have a description or be grouped in any way. This introduces tonnes of routes and they cannot easily be removed at once and clutter everything.

It may be more flexible and clean to set them up using something like Policy-Based Routing.

Run Ubiquity UNMS in LXC container on ProxMox

Note: This is not a complete guide, general container configuration steps, etc. are ommited assuming that they are obvious to the skilled reader.

The whole process is painless and takes ~15min.

Based on this post.

1. Create container

Create an LXC container using an image with one of the officially supported distros:

  • Ubuntu 16
  • Ubuntu 18
  • Debian 9

2. Set up the system

  1. Install docker, if on Ubuntu you can use the Official Guide.

  2. Install docker service overrides:

mkdir -p /etc/systemd/system/containerd.service.d
echo -e "[Service]\nExecStartPre=\n" > /etc/systemd/system/containerd.service.d/override.conf
systemctl daemon-reload
systemctl start docker
systemctl enable docker

3. Set up proxmox container options

Set up container options needed for running docker:

features:  keyctl=1,nesting=1
  • Add it via Options tab in the web GUI
  • Edit the file ``/etc/pve/lxc/.conf`
  • Use the pct CLI tool

4. Run UNMS installer in the container

Follow the official installation guide.

curl -fsSL https://unms.com/v1/install > /tmp/unms_inst.sh && sudo bash /tmp/unms_inst.sh

5. Perform initial UNMS setup and register your devices

See: The UNMS Key and the Device Registration Process.

Or just go to the network address of the running container 🤞

TODO

Write down:

  • SSH Key auth
  • Set up HTTPS certs with LE via ACME.sh

Also: Automate all of this with ansible.

#!/bin/bash
##################################################################
# *** VyOS / EdgeRouter Configuration Script *** #
# #
# Licensed under MIT (c) 2020 Filip Sobalski <pinkeen@gmail.com> #
##################################################################
set -e
if (( $# != 2 )); then
cat<<EOF
*** VyOS / EdgeRouter Configuration Script ***"
# Licensed under MIT (c) 2020 Filip Sobalski <pinkeen@gmail.com>
Job: Route traffic for AWS region subnets to an interface
Usage: $0 <aws-region> <target-interface> [mode]
Args:
aws-region name of target AWS region
target-interface name of interface to route traffic to
mode (default: set) set or delete the routes
EOF
exit 1
fi
MODE="${3:-set}"
TARGET_IFACE="$2"
AWS_REGION="$1"
aws_region_subnets() {
local AWS_REGION="$1"
curl -sL https://ip-ranges.amazonaws.com/ip-ranges.json | python -c 'import sys, json; region = sys.argv[1]; sys.stdout.write(str.join("\n", sorted([prefix["ip_prefix"] for prefix in (json.loads(sys.stdin.read()))["prefixes"] if "ip_prefix" in prefix and prefix["region"] == region])) + "\n");' "$AWS_REGION"
}
vrun() { echo "[CFG CMD] $@"; /opt/vyatta/bin/vyatta-op-cmd-wrapper "$@"; }
vcfg() { echo "[OP CMD] $@"; /opt/vyatta/sbin/vyatta-cfg-cmd-wrapper "$@"; }
# Ask for confirmation when interactive shell
if [[ ! "$-" != *i* ]] || [[ -z "$PS1" ]] ; then
read -p "Will route traffic for AWS subnets in region $AWS_REGION to interface $TARGET_IFACE, ar you sure? [Y\N] " CONTINUE
if [[ ! $CONTINUE =~ ^[Yy] ]] ; then
echo "Aborted" >&2
exit 9
fi
fi
AWS_SUBNETS="$(aws_region_subnets "$AWS_REGION")"
vcfg begin
# Disable error exit as the python script returns duplicates and some commands will fai
# there's no `unique` command in bash and I'm too lazy to fix the script 😅
set +e
for AWS_SUBNET in $AWS_SUBNETS ; do
vcfg $MODE protocols static interface-route $AWS_SUBNET next-hop-interface $TARGET_IFACE
done
set -e
echo -e "\n---\n"
vcfg commit
vcfg end
##################################################################
# *** VyOS / EdgeRouter Interactive Shell Setup *** #
# #
# Licensed under MIT (c) 2020 Filip Sobalski <pinkeen@gmail.com> #
##################################################################
# Make triple-sure we're in interactive shell not to break anything
[[ "$-" != *i* ]] && return
[[ ! -z "$PS1" ]] && return
export HISTFILE="$HOME/.bash_history"
export HIST_STAMPS="yyyy-mm-dd"
export HISTSIZE=200
export HISTFILESIZE=10000
export HISTCONTROL="erasedups:ignoreboth"
export HISTTIMEFORMAT='%F %T '
# Enable history niceties completion search
shopt -s cmdhist
shopt -s lithist
shopt -s histappend
shopt -s histreedit
shopt -s histverify
# History search with arrow up/down
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
# Jump to next/prev words with option(alt)+left/right
bind '"\e[C": forward-char'
bind '"\e[D": backward-char'
bind '"\e[1;5C": forward-word'
bind '"\e[1;5D": backward-word'
if which ccze >/dev/null 2>&1 ; then
ccze() { command ccze -A -o nolookups ; }
function ll() {
ls -alsh "$@" | ccze
}
function psa() {
ps auxf "$@" | ccze
}
function h() {
history "$@" | ccze
}
else
alias ll='ls -alsh'
alias psa='ps auxf'
fi
alias dmesg='dmesg -t'
alias l='ll'
# Bash function overloading code via https://stackoverflow.com/a/18839557
vhk_func_cpy() {
test -n "$(declare -f "$1")" || return
eval "${_/$1/$2}"
}
vhk_func_ren() {
copy_function "$@" || return
unset -f "$1"
}
vhk_cfg_prompt() {
# Vyatta configuration edit mode labels
# See: https://wiki.vyos.net/wiki/Cli-shell-api
cli-shell-api inSession || return
echo -n "\[\e[0;36m\][edit]\[\e[0m\] "
cli-shell-api sessionChanged >/dev/null 2>&1 && echo -n "\[\e[0;33m\]#changed\[\e[0m\] "
cli-shell-api sessionUnsaved >/dev/null 2>&1 && echo -n "\[\e[0;91m\]!saved\[\e[0m\] "
echo -n "\n"
}
vhk_prompt() {
history -a; PS1="$(vhk_cfg_prompt)${VHK_PS1}"
}
if [ "`id -u`" -eq 0 ]; then
export VHK_PS1="\[\e[1;31m\]\u\[\e[0;32m\]@\h\[\e[0m\] \[\e[0;94m\]\w\[\e[0m\] \[\e[1;32m\]->\[\e[0m\] "
else
export VHK_PS1="\[\e[0;33m\]\u\[\e[0;32m\]@\h\[\e[0m\] \[\e[0;94m\]\w\[\e[0m\] \[\e[1;32m\]->\[\e[0m\] "
fi
unset PS1
export VHK_PROMPT_COMMAND_ORIG="$PROMPT_COMMAND"; export PROMPT_COMMAND="vhk_prompt"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment