Skip to content

Commit

Permalink
Remove hardcoded port 8080 and replace with configurable port (#7)
Browse files Browse the repository at this point in the history
This PR is:

* replacing the hardcoded port 8080 used by DHCP client backend with a configurable port, which defaults to 8967 (much less common than 8080 to make port conflicts less likely)
* improving hostname and MAC address validations on the addon configuration using regex
  • Loading branch information
f18m authored Sep 29, 2024
1 parent f4a1936 commit d908671
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 18 deletions.
21 changes: 14 additions & 7 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
# as reported by the Github Action workflow 'publish.yaml', so that you can force HomeAssistant
# to use the docker image of that feature branch instead of the docker image of 'main', by pointing
# HomeAssistant to that feature branch
version: 1.1.0
slug: dnsmasq-dhcp
name: Dnsmasq-DHCP
version: beta
slug: dnsmasq-dhcp-beta
name: Dnsmasq-DHCP BETA
description: A DHCP server based on dnsmasq
url: https://github.com/f18m/ha-addon-dnsmasq-dhcp-server/tree/main
advanced: true
Expand Down Expand Up @@ -51,13 +51,17 @@ options:
end_ip: 192.168.1.250
ip_address_reservations:
- mac: aa:bb:cc:dd:ee:ff
name: "An important host with a static IP address assigned"
name: "An-important-host-with-reserved-IP"
ip: 192.168.1.15
dhcp_clients_friendly_names:
- mac: dd:ee:aa:dd:bb:ee
name: "This is a friendly name to label this host, even if it gets a dynamic IP"
log_dhcp: true
log_web_ui: false
# this addon uses "host_network: true" so the internal HTTP server will bind on the interface
# provided as network.interface and will occupy a port there; the following parameter makes
# that port configurable to avoid conflicts with other services
web_ui_port: 8976
schema:
default_lease: str
address_reservation_lease: str
Expand All @@ -75,13 +79,16 @@ schema:
end_ip: str
ip_address_reservations:
- ip: str
mac: str
name: str
mac: match(^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$)
# the name in this case must be a valid hostname as per RFC 1123 since it is passed to dnsmasq
# that will refuse to start if an invalid hostname format is used
name: match(^[a-zA-Z0-9\-.]*$)
dhcp_clients_friendly_names:
- mac: str
- mac: match(^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$)
name: str
log_dhcp: bool
log_web_ui: bool
web_ui_port: int
startup: system
privileged:
- NET_ADMIN
28 changes: 21 additions & 7 deletions dhcp-clients-webapp-backend/pkg/uibackend/uibackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/netdata/go.d.plugin/pkg/iprange"
)

var bindAddress = ":8080"
var defaultDnsmasqLeasesFile = "/data/dnsmasq.leases"
var defaultHomeAssistantConfigFile = "/data/options.json"
var dnsmasqMarkerForMissingHostname = "*"
Expand Down Expand Up @@ -114,8 +113,9 @@ type UIBackend struct {
dhcpEndIP net.IP

// the actual HTTP server
server http.Server
upgrader websocket.Upgrader
serverPort int
server http.Server
upgrader websocket.Upgrader

// map of connected websockets
clients map[*websocket.Conn]bool
Expand All @@ -125,10 +125,10 @@ type UIBackend struct {
dhcpClientData []DhcpClientData
dhcpClientDataLock sync.Mutex

// ch used to broadcast tabular data from backend->frontend
// channel used to broadcast tabular data from backend->frontend
broadcastCh chan []DhcpClientData

// ch used to link a goroutine watching for DHCP lease file changes and the lease file processor
// channel used to link a goroutine watching for DHCP lease file changes and the lease file processor
leasesCh chan []*dnsmasq.Lease
}

Expand All @@ -145,7 +145,7 @@ func NewUIBackend() UIBackend {
},
},
server: http.Server{
Addr: bindAddress,
Addr: "",
Handler: nil,
},
}
Expand Down Expand Up @@ -374,6 +374,8 @@ type AddonConfig struct {

LogDHCP bool `json:"log_dhcp"`
LogWebUI bool `json:"log_web_ui"`

WebUIPort int `json:"web_ui_port"`
}

func (b *UIBackend) readAddonConfig() error {
Expand Down Expand Up @@ -401,6 +403,17 @@ func (b *UIBackend) readAddonConfig() error {
// convert DHCP IP strings to net.IP
b.dhcpStartIP = net.ParseIP(cfg.DhcpRange.StartIP)
b.dhcpEndIP = net.ParseIP(cfg.DhcpRange.EndIP)
if b.dhcpStartIP == nil || b.dhcpEndIP == nil {
log.Default().Fatalf("Invalid DHCP range found in addon config file")
return os.ErrInvalid // I'm lazy, recycle a similar error type
}

// ensure we have a valid port for web UI
if cfg.WebUIPort <= 0 || cfg.WebUIPort > 32768 {
log.Default().Fatalf("Invalid Web UI port in addon config file")
return os.ErrInvalid // I'm lazy, recycle a similar error type
}
b.serverPort = cfg.WebUIPort

// convert to a slice of DhcpClientFriendlyName instances
for _, client := range cfg.DhcpClientsFriendlyNames {
Expand Down Expand Up @@ -464,7 +477,8 @@ func (b *UIBackend) ListenAndServe() error {
go b.broadcastUpdatesToClients()

// Start server
log.Default().Printf("Starting server to listen on %s\n", bindAddress)
log.Default().Printf("Starting server to listen on port %d\n", b.serverPort)
b.server.Addr = fmt.Sprintf(":%d", b.serverPort)
b.server.Handler = mux
return b.server.ListenAndServe()
}
5 changes: 5 additions & 0 deletions rootfs/etc/cont-init.d/32-nginx_ingress.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ bashio::log.info "Configuring nginx ingress..."
declare ingress_interface
declare ingress_port
declare ingress_entry
declare web_ui_port

ingress_port=$(bashio::addon.ingress_port)
ingress_interface=$(bashio::addon.ip_address)
ingress_entry=$(bashio::addon.ingress_entry)
web_ui_port=$(bashio::config 'web_ui_port')

if [ -z "$ingress_port" ]; then
ingress_port=8100
Expand All @@ -26,3 +28,6 @@ sed -i "s/%%port%%/${ingress_port}/g" /etc/nginx/servers/ingress.conf
sed -i "s/%%interface%%/${ingress_interface}/g" /etc/nginx/servers/ingress.conf
sed -i "s|%%ingress_entry%%|${ingress_entry}|g" /etc/nginx/servers/ingress.conf
sed -i "s|%%ingress_entry%%|${ingress_entry}|g" /etc/nginx/servers/ssl.conf

sed -i "s|%%web_ui_port%%|${web_ui_port}|g" /etc/nginx/servers/ingress.conf
sed -i "s|%%web_ui_port%%|${web_ui_port}|g" /etc/nginx/servers/ssl.conf
2 changes: 1 addition & 1 deletion rootfs/etc/nginx/servers/ingress.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ server {

location / {
# Proxy
proxy_pass http://127.0.0.1:8080/;
proxy_pass http://127.0.0.1:%%web_ui_port%%/;

proxy_read_timeout 30000;
proxy_redirect off;
Expand Down
2 changes: 1 addition & 1 deletion rootfs/etc/nginx/servers/ssl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ server {
}

location %%ingress_entry%%/ {
set $upstream_port 8080;
set $upstream_port %%web_ui_port%%;
proxy_pass http://127.0.0.1:$upstream_port;
}
}
7 changes: 5 additions & 2 deletions translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@ configuration:
# description: The last IP address of the DHCP range that defines the DHCP address pool.
ip_address_reservations:
name: IP Address Reservations
description: List of MAC addresses / IP addresses pairs that are reserved.
description: List of MAC addresses / IP addresses pairs that are reserved. Strict regex validation is performed on MAC addresses and hostnames (use alphanumeric chars plus dot or hyphens only).
dhcp_clients_friendly_names:
name: DHCP Clients Friendly Names
description: List of MAC addresses / friendly-name pairs to help identify the DHCP clients in the Web UI.
description: List of MAC addresses / friendly-name pairs to help identify the DHCP clients in the Web UI. Strict regex validation is performed on MAC addresses.

log_dhcp:
name: Log DHCP
description: Log all details about DHCP requests served by the server
log_web_ui:
name: Log Web UI
description: Log all HTTP requests served by the add-on UI
web_ui_port:
name: Web UI Port
description: Port used by the internal HTTP server. Change only if you get a conflict on the default port.

0 comments on commit d908671

Please sign in to comment.