Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"permissions": {
"allow": [
"Bash(ansible-playbook *)",
"Bash(ansible-vault *)",
"Bash(ansible *)",
"Bash(ansible-galaxy *)",
"Bash(docker run *)",
"Bash(docker exec *)",
"Bash(docker rm *)",
"Bash(docker pull *)",
"Bash(docker cp *)",
"Bash(cp vault/secrets.yml.example *)",
"Bash(git *)",
"Bash(gh *)",
"Bash(bash -n *)",
"Bash(python3 *)",
"Bash(tee *)",
"Bash(curl *)",
"Bash(mkdir *)",
"Bash(printf *)",
"Bash(chmod *)",
"Write(inventory/ci-local.ini)",
"Write(inventory/host_vars/local-test.yml)"
]
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ vault/secrets.yml

# Temporary files from local Docker test runs
inventory/ci-local.ini
inventory/ci-test-runner.ini
inventory/hosts-docker-test.ini

# Old vault passwords
vault/.vault_pass_old
Expand Down
28 changes: 24 additions & 4 deletions configure_and_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ PREF_OPENRVDAS_AUTOSTART='${OPENRVDAS_AUTOSTART}'
PREF_INSTALL_GUI='${INSTALL_GUI}'
PREF_INSTALL_FIREWALLD='${INSTALL_FIREWALLD}'
PREF_INSTALL_UFW='${INSTALL_UFW}'
PREF_UFW_LOCALHOST_ONLY='${UFW_LOCALHOST_ONLY}'
PREF_TCP_PORTS_TO_OPEN='${TCP_PORTS_TO_OPEN}'
PREF_UDP_PORTS_TO_OPEN='${UDP_PORTS_TO_OPEN}'
PREF_INSTALL_SIMULATE_NBP='${INSTALL_SIMULATE_NBP}'
Expand Down Expand Up @@ -535,11 +536,13 @@ fi
section "Installation"

ask INSTALL_ROOT "Installation root directory" "${PREF_INSTALL_ROOT:-/opt}"
if [[ "$INSTALL_ROOT" == /home/* ]]; then
if [[ "$INSTALL_ROOT" != /opt* && "$INSTALL_ROOT" != /srv* && "$INSTALL_ROOT" != /var* && "$INSTALL_ROOT" != /usr/local* ]]; then
echo
echo "WARNING: Installing under a home directory can cause nginx 502 errors."
echo "nginx (www-data) cannot traverse home directories without world-execute"
echo "permission. The playbook will set this automatically, but /opt is safer."
echo "WARNING: Installing outside a standard system directory (/opt, /srv, etc.)."
echo "nginx and supervisord must be able to traverse every directory in the path."
echo "Restrictive permissions (e.g. /home dirs are chmod 750 on Ubuntu 24.04,"
echo "/root is 700) will block access. The playbook will chmod o+x all parent"
echo "directories automatically, but /opt is safest for production vessel systems."
echo
fi
if [ "$OS_TYPE" != "macos" ]; then
Expand Down Expand Up @@ -585,6 +588,8 @@ ask_yn INSTALL_GUI "Install nginx + uWSGI web interface?" "${PREF_INSTALL_GUI:-y
if [ "$OS_TYPE" = "centos" ] || [ "$OS_TYPE" = "rocky" ] || [ "$OS_TYPE" = "alma" ]; then
ask_yn INSTALL_FIREWALLD "Configure firewalld?" "${PREF_INSTALL_FIREWALLD:-no}"
INSTALL_UFW="no"
UFW_LOCALHOST_ONLY="no"
UFW_OPENRVDAS_SOURCE="any"
if [ "$INSTALL_FIREWALLD" = "yes" ]; then
ask TCP_PORTS_TO_OPEN "Extra TCP ports to open (space-separated, blank for none)" "${PREF_TCP_PORTS_TO_OPEN:-}"
ask UDP_PORTS_TO_OPEN "Extra UDP ports to open (space-separated, blank for none)" "${PREF_UDP_PORTS_TO_OPEN:-}"
Expand All @@ -596,15 +601,29 @@ elif [ "$OS_TYPE" = "ubuntu" ] || [ "$OS_TYPE" = "debian" ] || [ "$OS_TYPE" = "r
ask_yn INSTALL_UFW "Configure ufw firewall?" "${PREF_INSTALL_UFW:-no}"
INSTALL_FIREWALLD="no"
if [ "$INSTALL_UFW" = "yes" ]; then
echo " UDP instrument data ports (6224-6226) will be opened automatically."
echo " CachedDataServer (8766) is accessed via the nginx proxy and is not opened."
echo " On an isolated vessel LAN the UDP ports can be open to all hosts; on a"
echo " laptop or dev machine restrict them to localhost only."
ask_yn UFW_LOCALHOST_ONLY "Restrict UDP instrument data ports to localhost only?" "${PREF_UFW_LOCALHOST_ONLY:-no}"
if [ "$UFW_LOCALHOST_ONLY" = "yes" ]; then
UFW_OPENRVDAS_SOURCE="127.0.0.1"
else
UFW_OPENRVDAS_SOURCE="any"
fi
ask TCP_PORTS_TO_OPEN "Extra TCP ports to open (space-separated, blank for none)" "${PREF_TCP_PORTS_TO_OPEN:-}"
ask UDP_PORTS_TO_OPEN "Extra UDP ports to open (space-separated, blank for none)" "${PREF_UDP_PORTS_TO_OPEN:-}"
else
UFW_LOCALHOST_ONLY="no"
UFW_OPENRVDAS_SOURCE="any"
TCP_PORTS_TO_OPEN="${PREF_TCP_PORTS_TO_OPEN:-}"
UDP_PORTS_TO_OPEN="${PREF_UDP_PORTS_TO_OPEN:-}"
fi
else
INSTALL_FIREWALLD="no"
INSTALL_UFW="no"
UFW_LOCALHOST_ONLY="no"
UFW_OPENRVDAS_SOURCE="any"
TCP_PORTS_TO_OPEN="${PREF_TCP_PORTS_TO_OPEN:-}"
UDP_PORTS_TO_OPEN="${PREF_UDP_PORTS_TO_OPEN:-}"
fi
Expand Down Expand Up @@ -792,6 +811,7 @@ openrvdas_autostart: $(yn_to_bool "$OPENRVDAS_AUTOSTART")
install_gui: $(yn_to_bool "$INSTALL_GUI")
install_firewalld: $(yn_to_bool "$INSTALL_FIREWALLD")
install_ufw: $(yn_to_bool "$INSTALL_UFW")
ufw_openrvdas_source: "${UFW_OPENRVDAS_SOURCE}"
tcp_ports_to_open: $(yaml_str_array "$TCP_PORTS_TO_OPEN")
udp_ports_to_open: $(yaml_str_array "$UDP_PORTS_TO_OPEN")

Expand Down
13 changes: 13 additions & 0 deletions inventory/group_vars/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ install_firewalld: false # configure firewalld (CentOS/RHEL only)
# Set install_ufw: true/false in host_vars to skip the prompt, or pass -e install_ufw=true.
# ufw_force_reset: true skips the "preserve existing rules?" prompt (useful in CI / non-interactive runs).

# ── OpenRVDAS data ports ──────────────────────────────────────────────────────
# CachedDataServer websocket port — used in supervisor templates only.
# ufw does NOT open this port: browser access is proxied via nginx /cds-ws,
# and logger processes connect via loopback.
openrvdas_data_port: 8766
# UDP ports used for instrument data broadcast between loggers.
openrvdas_udp_ports: [6224, 6225, 6226]

# ── ufw: UDP instrument data port source restriction ─────────────────────────
# "any" — open to all (isolated vessel LAN)
# "127.0.0.1" — localhost only (laptop / dev machine)
ufw_openrvdas_source: "any"

# ── Additional firewall ports ─────────────────────────────────────────────────
tcp_ports_to_open: []
udp_ports_to_open: []
Expand Down
19 changes: 19 additions & 0 deletions roles/common/tasks/directories.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
---
# nginx (www-data) and supervisord must be able to traverse every directory
# component of install_root. Standard locations (/opt, /srv, /var) are 755 by
# default, but home directories are 750 on Ubuntu 24.04, /root is 700, and
# arbitrary custom paths may have been created with restrictive permissions.
# Ensure all parent components are world-executable (o+x is idempotent on
# already-755 dirs and harmless on standard system directories).
- name: Ensure all parent directories of install_root are world-traversable
ansible.builtin.file:
path: "{{ item }}"
mode: "o+x"
loop: >-
{%- set parts = install_root.rstrip('/').split('/') -%}
{%- set result = [] -%}
{%- for i in range(2, parts | length) -%}
{%- set _ = result.append('/'.join(parts[:i])) -%}
{%- endfor -%}
{{ result }}
when: ansible_os_family != 'Darwin'

- name: Create install root directory
ansible.builtin.file:
path: "{{ install_root }}"
Expand Down
18 changes: 18 additions & 0 deletions roles/firewall/tasks/ufw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,24 @@
loop: "{{ udp_ports_to_open }}"
tags: [firewall]

# ── OpenRVDAS UDP instrument data ports ───────────────────────────────────────
# CachedDataServer (8766/tcp) is intentionally NOT opened here — browser access
# goes through the nginx /cds-ws proxy and local logger processes use loopback.
# UDP ports carry instrument data between loggers; they need to be reachable
# from the network on a vessel LAN, or from localhost only on a dev machine.
# ufw_openrvdas_source controls the allowed source:
# "any" — open to all (isolated vessel LAN)
# "127.0.0.1" — localhost only (laptop / dev machine)

- name: Open OpenRVDAS UDP instrument data ports
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: udp
from_ip: "{{ ufw_openrvdas_source }}"
loop: "{{ openrvdas_udp_ports }}"
tags: [firewall]

- name: Enable ufw
community.general.ufw:
state: enabled
Expand Down
9 changes: 0 additions & 9 deletions roles/nginx/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,3 @@
notify: reload supervisor
tags: [nginx]

- name: Grant nginx world-execute on home directory so it can reach the uwsgi socket
ansible.builtin.file:
path: "{{ install_root | regex_replace('^(/home/[^/]+).*', '\\1') }}"
mode: "o+x"
become: true
when:
- ansible_os_family != "Darwin"
- install_root is match('^/home/')
tags: [nginx]
2 changes: 1 addition & 1 deletion roles/supervisor/templates/openrvdas_cached_data.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; Do not edit by hand; re-run the Ansible playbook to regenerate.

[program:cached_data_server]
command={{ install_root }}/openrvdas/venv/bin/python server/cached_data_server.py --port 8766 --disk_cache /var/tmp/openrvdas/disk_cache --max_records 8640 -v
command={{ install_root }}/openrvdas/venv/bin/python server/cached_data_server.py --port {{ openrvdas_data_port }} --disk_cache /var/tmp/openrvdas/disk_cache --max_records 8640 -v
directory={{ install_root }}/openrvdas
autostart={{ openrvdas_autostart | lower }}
autorestart=true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; Do not edit by hand; re-run the Ansible playbook to regenerate.

[program:logger_manager]
command={{ install_root }}/openrvdas/venv/bin/python server/logger_manager.py --database django --data_server_websocket :8766 -v -V --no-console
command={{ install_root }}/openrvdas/venv/bin/python server/logger_manager.py --database django --data_server_websocket :{{ openrvdas_data_port }} -v -V --no-console
environment=PATH="{{ install_root }}/openrvdas/venv/bin:/usr/bin:/usr/local/bin"
directory={{ install_root }}/openrvdas
autostart={{ openrvdas_autostart | lower }}
Expand Down
Loading