commit d3299f884845b36df4e283986166da5b54a3f34e Author: John Burwell Date: Fri Apr 25 19:11:33 2025 -0500 Initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ansible/playbook.yml b/ansible/playbook.yml new file mode 100644 index 0000000..8f1eae7 --- /dev/null +++ b/ansible/playbook.yml @@ -0,0 +1,120 @@ +--- +- name: Ham Hotspot Bootstrap + hosts: localhost + become: yes + + vars_files: + - ../config/desired_state.yml + + tasks: + - name: Install base apt packages + apt: + name: + - ax25-tools + - ax25-apps + - libax25 + - dnsmasq + - hostapd + - python3-flask + - build-essential + - cmake + - git + state: present + update_cache: yes + + - name: Clone Direwolf from GitHub + git: + repo: 'https://github.com/wb2osz/direwolf.git' + dest: /usr/local/src/direwolf + update: no + + - name: Build Direwolf + shell: | + mkdir -p /usr/local/src/direwolf/build + cd /usr/local/src/direwolf/build + cmake .. + make -j4 + args: + chdir: /usr/local/src/direwolf + creates: /usr/local/src/direwolf/build/direwolf + + - name: Install Direwolf + shell: | + cd /usr/local/src/direwolf/build + make install + args: + chdir: /usr/local/src/direwolf/build + creates: /usr/local/bin/direwolf + + - name: Copy systemd service templates + copy: + src: ../systemd/ + dest: /lib/systemd/system/ + mode: '0644' + owner: root + group: root + + - name: Deploy Direwolf configuration + template: + src: ../templates/direwolf.conf.j2 + dest: /etc/ham-hotspot/direwolf-{{ radio.port_name }}.conf + mode: '0644' + + - name: Deploy hostapd configuration + template: + src: ../templates/hostapd.conf.j2 + dest: /etc/hostapd/hostapd.conf + mode: '0644' + + - name: Deploy dnsmasq configuration + template: + src: ../templates/dnsmasq.conf.j2 + dest: /etc/dnsmasq.d/ham-hotspot.conf + mode: '0644' + + - name: Deploy axports configuration + template: + src: ../templates/axports.j2 + dest: /etc/ax25/axports + mode: '0644' + + - name: Enable IP forwarding + copy: + dest: /etc/sysctl.d/ham-hotspot.conf + content: | + net.ipv4.ip_forward=1 + mode: '0644' + + - name: Reload systemd daemon + systemd: + daemon_reload: yes + + - name: Enable and start Direwolf instance + systemd: + name: direwolf@radio0.service + enabled: yes + state: started + + - name: Enable and start KISS TNC instance + systemd: + name: kisstnc@radio0.service + enabled: yes + state: started + + - name: Enable and start AX.25 daemon + systemd: + name: ax25d.service + enabled: yes + state: started + + - name: Enable and start hostapd + systemd: + name: hostapd.service + enabled: yes + state: started + + - name: Enable and start dnsmasq + systemd: + name: dnsmasq.service + enabled: yes + state: started diff --git a/config/desired-state.yml b/config/desired-state.yml new file mode 100644 index 0000000..7910984 --- /dev/null +++ b/config/desired-state.yml @@ -0,0 +1,17 @@ +# Configuration state for Ham Hotspot + +wifi: + ssid: HamHotspot + password: change_me_now + channel: 6 + +network: + lan_subnet: 192.168.73.0/24 + lan_gateway: 192.168.73.1 + +radio: + device: plughw:CARD=CODEC,DEV=0 + speed: 1200 + mycall: KI5QKX-11 + port_name: radio0 + ip_address: 44.31.1.1 diff --git a/systemd/ax25d.service b/systemd/ax25d.service new file mode 100644 index 0000000..e9234cf --- /dev/null +++ b/systemd/ax25d.service @@ -0,0 +1,14 @@ +[Unit] +Description=AX.25 Daemon (ax25d) +After=network.target syslog.target +Requires=network.target + +[Service] +Type=simple +ExecStart=/usr/sbin/ax25d -l +ExecReload=/bin/kill -SIGHUP $MAINPID +ExecStop=/bin/kill -SIGQUIT $MAINPID +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/systemd/direwolf@.service b/systemd/direwolf@.service new file mode 100644 index 0000000..4b3f7b5 --- /dev/null +++ b/systemd/direwolf@.service @@ -0,0 +1,20 @@ +[Unit] +Description=Direwolf %I soundcard modem +After=network.target + +[Service] +Type=simple + +PrivateTmp=true +StateDirectory=direwolf +ExecStart=/usr/local/bin/direwolf -t 0 -p -c /etc/ham-hotspot/direwolf-%i.conf -q h -q d +Restart=unless-stopped +# Relocate /tmp/kisstnc symlink to /run/direwolf/. +ExecStartPre=/usr/bin/mkdir -p /run/direwolf +ExecStartPost=/bin/timeout 10 /bin/sh -c 'while ! test -c /tmp/kisstnc; do sleep 1; done; cp -a /tmp/kisstnc /run/direwolf/%i' + +# Clean up symlink on exit. +ExecStopPost=/bin/rm -f /run/direwolf/%i + +[Install] +WantedBy=multi-user.target diff --git a/systemd/kisstnc@.service b/systemd/kisstnc@.service new file mode 100644 index 0000000..f990c37 --- /dev/null +++ b/systemd/kisstnc@.service @@ -0,0 +1,14 @@ +[Unit] +Description=Attach AX.25 KISS device %I +Requires=direwolf@%i.service +After=direwolf@%i.service +AssertPathExists=/run/direwolf/%i + +[Service] +Type=oneshot +ExecStart=/usr/sbin/kissattach /run/direwolf/%i %i +ExecStartPost=/usr/sbin/kissparms -c 1 -p %i +RemainAfterExit=true + +[Install] +WantedBy=multi-user.target diff --git a/templates/axports.j2 b/templates/axports.j2 new file mode 100644 index 0000000..fc080cb --- /dev/null +++ b/templates/axports.j2 @@ -0,0 +1 @@ +radio0 {{ radio.mycall }} 0 255 1 PiRadio AX.25 port diff --git a/templates/direwolf.conf.j2 b/templates/direwolf.conf.j2 new file mode 100644 index 0000000..1b429bb --- /dev/null +++ b/templates/direwolf.conf.j2 @@ -0,0 +1,22 @@ +# Template: direwolf.conf.j2 +# Auto-generated by Ansible based on desired_state.yml + +# Audio input device +ADEVICE {{ radio.device }} + +# Set the call sign +MYCALL {{ radio.mycall }} + +# Define the modem type (assuming a basic 1200 or 9600 baud AFSK modem) +MODEM {{ radio.speed }} + +# Optional: AX.25 parameters (could fine-tune later) +TXDELAY 30 +TXTAIL 10 +DWAIT 0 +SLOTTIME 100 +PERSIST 63 +FIX_BITS 1 AX25 + +# Log settings +LOGDIR /var/log/direwolf diff --git a/templates/dnsmasq.conf.j2 b/templates/dnsmasq.conf.j2 new file mode 100644 index 0000000..a395489 --- /dev/null +++ b/templates/dnsmasq.conf.j2 @@ -0,0 +1,4 @@ +interface=wlan0 +dhcp-range={{ network.lan_gateway | regex_replace('\.1$', '.100') }},{{ network.lan_gateway | regex_replace('\.1$', '.200') }},12h +dhcp-option=3,{{ network.lan_gateway }} +dhcp-option=6,8.8.8.8 diff --git a/templates/hostapd.conf.j2 b/templates/hostapd.conf.j2 new file mode 100644 index 0000000..4e9c58b --- /dev/null +++ b/templates/hostapd.conf.j2 @@ -0,0 +1,14 @@ +interface=wlan0 +driver=nl80211 +ssid={{ wifi.ssid }} +hw_mode=g +channel={{ wifi.channel }} +wmm_enabled=0 +macaddr_acl=0 +auth_algs=1 +ignore_broadcast_ssid=0 +wpa=2 +wpa_passphrase={{ wifi.password }} +wpa_key_mgmt=WPA-PSK +wpa_pairwise=TKIP +rsn_pairwise=CCMP