aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/test.yml34
-rw-r--r--action.yml160
2 files changed, 194 insertions, 0 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..7b046e9
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,34 @@
+name: Test
+
+on:
+ push:
+ pull_request:
+ schedule:
+ # Weekly, at 5:45 AM on Friday (somewhat randomly chosen).
+ - cron: '45 5 * * 5'
+ workflow_dispatch:
+
+jobs:
+ test:
+ strategy:
+ matrix:
+ os: [ubuntu-18.04, ubuntu-20.04, ubuntu-latest]
+ runs-on: '${{ matrix.os }}'
+ name: 'Test: ${{ matrix.os }}'
+ defaults:
+ run:
+ shell: bash
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Set up WireGuard
+ uses: ./
+ with:
+ endpoint: '${{ secrets.ENDPOINT }}'
+ endpoint_public_key: '${{ secrets.ENDPOINT_PUBLIC }}'
+ ips: '${{ secrets.IPS }}'
+ private_key: '${{ secrets.PRIVATE }}'
+ preshared_key: '${{ secrets.PRESHARED }}'
+ allowed_ips: '${{ secrets.ALLOWED_IPS }}'
+ - name: Check endpoint
+ run: ping -W 10 -c 5 -- '${{ secrets.ENDPOINT_PRIVATE_IP }}'
diff --git a/action.yml b/action.yml
new file mode 100644
index 0000000..77e4827
--- /dev/null
+++ b/action.yml
@@ -0,0 +1,160 @@
+name: Set up WireGuard
+description: Set up WireGuard connection
+
+inputs:
+ endpoint:
+ description: Endpoint in the HOST:PORT format
+ required: true
+ endpoint_public_key:
+ description: Public key of the endpoint
+ required: true
+ ips:
+ description: Comma-separated list of IP addresses
+ required: true
+ private_key:
+ description: Private key
+ required: true
+ preshared_key:
+ description: Preshared key
+ required: false
+ allowed_ips:
+ description: Comma-separated list of netmasks
+ required: true
+
+runs:
+ using: composite
+ steps:
+ - run: |
+ set -o errexit -o pipefail -o nounset
+
+ readonly endpoint='${{ inputs.endpoint }}'
+ readonly endpoint_public_key='${{ inputs.endpoint_public_key }}'
+ readonly ips='${{ inputs.ips }}'
+ readonly private_key='${{ inputs.private_key }}'
+ readonly preshared_key='${{ inputs.preshared_key }}'
+ readonly allowed_ips='${{ inputs.allowed_ips }}'
+
+ readonly minport=51000
+ readonly maxport=51999
+
+ ifname="wg$( openssl rand -hex 4 )"
+ readonly ifname
+ port="$( shuf "--input-range=$minport-$maxport" --head-count=1 )"
+ readonly port
+
+ via_systemd() {
+ local netdev_path
+ netdev_path="/etc/systemd/network/$ifname.netdev"
+ local network_path
+ network_path="/etc/systemd/network/$ifname.network"
+
+ local netdev_contents
+ netdev_contents="
+ [NetDev]
+ Name=$ifname
+ Kind=wireguard
+ Description=WireGuard tunnel $ifname
+
+ [WireGuard]
+ ListenPort=$port
+ PrivateKey=$private_key
+
+ [WireGuardPeer]
+ Endpoint=$endpoint
+ PublicKey=$endpoint_public_key
+ AllowedIPs = $allowed_ips"
+
+ if [ -n "$preshared_key" ]; then
+ netdev_contents="$netdev_contents
+ PresharedKey=$preshared_key"
+ fi
+
+ local network_contents
+ network_contents="
+ [Match]
+ Name=$ifname
+
+ [Network]"
+
+ local delim=,
+ local ip
+ while IFS= read -d "$delim" -r ip; do
+ network_contents="$network_contents
+ Address=$ip"
+ done < <( printf -- "%s$delim\\0" "$ips" )
+
+ sudo touch -- "$netdev_path"
+ sudo chown -- root:systemd-network "$netdev_path"
+ sudo chmod -- 0640 "$netdev_path"
+ sudo touch -- "$network_path"
+ echo "$netdev_contents" | sudo tee -- "$netdev_path" > /dev/null
+ echo "$network_contents" | sudo tee -- "$network_path" > /dev/null
+
+ sudo systemctl restart systemd-networkd
+ sudo systemctl status systemd-networkd
+ }
+
+ install_wg_tools() {
+ sudo apt-get update
+ sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends wireguard-tools
+ }
+
+ readonly private_key_path=/tmp/private.key
+ readonly preshared_key_path=/tmp/preshared.key
+
+ wg_tools_cleanup() {
+ rm -f -- "$private_key_path"
+ rm -f -- "$preshared_key_path"
+ }
+
+ via_wg_tools() {
+ install_wg_tools
+ trap wg_tools_cleanup EXIT
+
+ (
+ set -o errexit -o nounset -o pipefail
+ umask 0077
+ echo "$private_key" > "$private_key_path"
+ if [ -n "$preshared_key" ]; then
+ echo "$preshared_key" > "$preshared_key_path"
+ fi
+ )
+
+ sudo ip link add dev "$ifname" type wireguard
+
+ local delim=,
+ local ip
+ while IFS= read -d "$delim" -r ip; do
+ sudo ip addr add "$ip" dev "$ifname"
+ done < <( printf -- "%s$delim\\0" "$ips" )
+
+ sudo wg set "$ifname" \
+ listen-port "$port" \
+ private-key "$private_key_path"
+
+ if [ -z "$preshared_key" ]; then
+ sudo wg set "$ifname" \
+ peer "$endpoint_public_key" \
+ endpoint "$endpoint" \
+ allowed-ips "$allowed_ips"
+ else
+ sudo wg set "$ifname" \
+ peer "$endpoint_public_key" \
+ preshared-key "$preshared_key_path" \
+ endpoint "$endpoint" \
+ allowed-ips "$allowed_ips"
+ fi
+
+ sudo ip link set "$ifname" up
+ }
+
+ # systemd-networkd greets me with 'Temporary failure in name
+ # resolution' on Bionic when using a hostname instead of an IP address
+ # for endpoint. God knows why!
+ #via_systemd
+ via_wg_tools
+ shell: bash
+
+branding:
+ icon: star
+ color: green