Skip to content

Instantly share code, notes, and snippets.

@ftk
Last active May 27, 2026 10:23
Show Gist options
  • Select an option

  • Save ftk/8d179876d5eac47b670190bfbc1b6faa to your computer and use it in GitHub Desktop.

Select an option

Save ftk/8d179876d5eac47b670190bfbc1b6faa to your computer and use it in GitHub Desktop.
Simple AmneziaWG config generator. AmneziaWG is a wireguard fork with obfuscated headers. Example usage: env num_peers=3 bash ./awg-mkconfig.sh 1.2.3.4 ens3
#!/usr/bin/env bash
## Simple config generator for AmneziaWG server and clients (1 client by default) with random headers.
## It will generate files wg0s.conf, wg0c2.conf, ...
## wg0s.conf must be placed in /etc/amnezia/amneziawg/ on the server, other files must be distributed to clients.
## Usage: ./awg-mkconfig.sh [remote ip] [remote wan iface] (remote ssh name - optional)
## To get remote interface run "ip address show" on the server. Usually it starts with "ens".
## Environment variables:
## num_peers=2 - increase to generate configs for more than 1 client
## port - defaults to random port from 1024 to 33792
## subnet=10.100.0 - first 3 octets for awg interface
##
## amneziawg-tools or wireguard-tools must be installed for the script to work.
set -eo pipefail
# print help
[[ $# -eq 0 || $1 == --help ]] && exec sed -n 's/^## //p' -- "$0"
remoteip="${1}" # $(curl -s -4 ifconfig.co)
iface_wan="${2-eth0}"
ssh_remote="${3-root@$remoteip}"
subnet="${subnet-10.100.0}" # /24 subnet prefix
port="${port-$(( RANDOM + 1024 ))}"
awg="${awg-$(command -v awg || command -v amneziawg || command -v wg)}"
span=$((1000000000 + ((RANDOM<<15) | RANDOM) ))
# generate obfuscation parameters
# Generate "good enough" non overlapping ranges. h4 is a data packet so it should have maximum entropy. Then the span shrinks exponentially, ensuring that the selection will terminate.
while (( h4 < 5 || h4_end > 0xffffffff )); do
h4=$(( ((RANDOM<<30) | (RANDOM<<15) | RANDOM) & 0xffffffff ));
h4_end=$((h4 + span))
span=$((span - span / 4))
done
while (( h3 < 5 || h3_end > 0xffffffff || (h3 >= h4 && h3 <= h4_end) || (h3_end >= h4 && h3_end <= h4_end) )); do
h3=$(( ((RANDOM<<30) | (RANDOM<<15) | RANDOM) & 0xffffffff ));
h3_end=$((h3 + span))
span=$((span - span / 4))
done
while (( h2 < 5 || h2_end > 0xffffffff || (h2 >= h4 && h2 <= h4_end) || (h2_end >= h4 && h2_end <= h4_end)|| (h2 >= h3 && h2 <= h3_end) || (h2_end >= h3 && h2_end <= h3_end))); do
h2=$(( ((RANDOM<<30) | (RANDOM<<15) | RANDOM) & 0xffffffff ));
h2_end=$((h2 + span))
span=$((span - span / 4))
done
while (( h1 < 5 || h1_end > 0xffffffff || (h1 >= h4 && h1 <= h4_end) || (h1_end >= h4 && h1_end <= h4_end)|| (h1 >= h3 && h1 <= h3_end) || (h1_end >= h3 && h1_end <= h3_end)|| (h1 >= h2 && h1 <= h2_end) || (h1_end >= h2 && h1_end <= h2_end))); do
h1=$(( ((RANDOM<<30) | (RANDOM<<15) | RANDOM) & 0xffffffff ));
h1_end=$((h1 + span))
span=$((span - span / 4))
done
s1="$(( (RANDOM & 0xff) + 1 ))"
while [[ ${s2-0} -lt 1 || $s2 -eq $((s1 + 56)) ]]; do
s2=$(( RANDOM & 0xff ))
done
s3=$(((RANDOM & 0xff)+1))
s4=$(((RANDOM & 0x3f)+1))
# generate server key
server_key="$($awg genkey)"
server_pubkey="$(echo "$server_key" | $awg pubkey)"
cat > wg0s.conf <<EOF
# Auto generated by $0 $@
[Interface]
Address = $subnet.1/24, fd00:100::1/64
PrivateKey = $server_key
ListenPort = $port
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o $iface_wan -j MASQUERADE
PostUp = sysctl -w net.ipv6.conf.all.forwarding=1; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $iface_wan -j MASQUERADE
#PostUp = systemctl restart miniupnpd.service
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o $iface_wan -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $iface_wan -j MASQUERADE
#PostDown = systemctl stop miniupnpd.service
H1 = $h1-$h1_end
H2 = $h2-$h2_end
H3 = $h3-$h3_end
H4 = $h4-$h4_end
S1 = $s1
S2 = $s2
S3 = $s3
S4 = $s4
Jc = $(((RANDOM & 0x7) + 1))
Jmin = 16
Jmax = 1024
MTU = 1420
EOF
# generate peers
for i in $(seq 2 "${num_peers-2}")
do
peer_key="$($awg genkey)"
psk="PresharedKey = $($awg genpsk)" # additional encryption layer (comment this line to disable)
echo "Generating peer ${i}..."
cat >> wg0s.conf <<EOF
[Peer]
PublicKey = $(echo "$peer_key" | $awg pubkey)
AllowedIPs = $subnet.$i/32, fd00:100::$i/128
${psk-}
EOF
cat > "wg0c$i.conf" <<EOF
# Auto generated by $0 $@
[Interface]
Address = $subnet.$i, fd00:100::$i/128
PrivateKey = $peer_key
H1 = $h1-$h1_end
H2 = $h2-$h2_end
H3 = $h3-$h3_end
H4 = $h4-$h4_end
S1 = $s1
S2 = $s2
S3 = $s3
S4 = $s4
Jc = $(((RANDOM & 0x7) + 1))
Jmin = 16
Jmax = 1024
MTU = 1420
[Peer]
PublicKey = $server_pubkey
Endpoint = $remoteip:$port
# PersistentKeepalive = 25 # if port forwarding is used
# forward all traffic
AllowedIPs = 0.0.0.0/0, ::/0
# only direct connection
#AllowedIPs = $subnet.0/24, fd00:100::1/64
${psk-}
EOF
done
echo scp wg0s.conf "$ssh_remote:/etc/amnezia/amneziawg/wg0.conf"
echo ssh "$ssh_remote" systemctl enable --now [email protected]
echo
echo sudo mv wg0c2.conf /etc/amnezia/amneziawg/wg0.conf
echo sudo systemctl enable --now [email protected]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment