feat: add listen address configuration option#94
feat: add listen address configuration option#94yingzeliangzi wants to merge 1 commit intolich0821:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds configurable listen address support to improve security by defaulting to localhost (127.0.0.1) instead of binding to all interfaces (0.0.0.0). This prevents unauthorized public network access when no auth_token is configured.
Changes:
- Added
ListenAddrfield to configuration with 127.0.0.1 as the default - Created
UpdateNetworkmethod to update both port and listen address atomically - Updated UI to display and configure listen address with preset buttons for common values
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/config/config.go | Added ListenAddr field, getter/setter methods, validation, and storage persistence |
| internal/service/settings.go | Added UpdateNetwork method and listen address validation in UpdateConfig |
| internal/proxy/proxy.go | Modified server startup to bind to configured listen address instead of all interfaces |
| cmd/server/main.go | Added environment variable support for CCNEXUS_LISTEN_ADDR and updated logging |
| cmd/server/webui/api/config.go | Updated API endpoints to handle listen address in requests/responses |
| cmd/server/webui/ui/js/api.js | Modified updatePort to accept optional listenAddr parameter |
| cmd/desktop/app.go | Added UpdateNetwork method wrapper |
| cmd/desktop/frontend/wailsjs/* | Generated Wails bindings for UpdateNetwork method |
| cmd/desktop/frontend/src/*.js | Updated UI to support listen address configuration with presets |
| cmd/desktop/frontend/src/i18n/*.js | Added translations for listen address UI elements |
| cmd/desktop/frontend/src/style.css | Added CSS styles for listen address preset buttons |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return; | ||
| } | ||
|
|
||
| if (!listenAddr || /\s/.test(listenAddr)) { |
There was a problem hiding this comment.
The validation only checks for empty values and whitespace. Consider validating that the listen address is a valid IP address or hostname. Invalid addresses like "999.999.999.999" or malformed hostnames will pass this check and only fail at runtime when the server attempts to bind.
| if strings.TrimSpace(c.ListenAddr) == "" { | ||
| return fmt.Errorf("invalid listen address") | ||
| } |
There was a problem hiding this comment.
The validation only checks for empty/whitespace values but does not verify that the address is a valid IP address or hostname. Consider using net.ParseIP or similar validation to ensure the listen address is valid before attempting to bind to it. This would provide better error messages at configuration time rather than runtime.
| if strings.TrimSpace(req.ListenAddr) == "" { | ||
| WriteError(w, http.StatusBadRequest, "Invalid listen address") | ||
| return | ||
| } |
There was a problem hiding this comment.
The validation only checks for empty/whitespace values but does not verify that the address is a valid IP address or hostname. Consider adding proper validation to ensure the listen address format is valid before saving it to configuration.
| if strings.TrimSpace(listenAddr) == "" { | ||
| return fmt.Errorf("invalid listen address") | ||
| } |
There was a problem hiding this comment.
The validation only checks for empty/whitespace values. Consider adding validation to ensure the listen address is a valid IP address or hostname format using net.ParseIP or similar methods.
| listenAddrLabel: '监听地址:', | ||
| listenAddrPlaceholder: '例如:127.0.0.1', | ||
| listenAddrPresetPublic: '公网 0.0.0.0', | ||
| listenAddrPresetLAN: '局域网 192.168.0.0', |
There was a problem hiding this comment.
The preset value '192.168.0.0' is a network address, not a valid host IP to bind to. This should likely be '192.168.0.1' or another valid host address in the private range. Binding to .0.0 addresses (network addresses) may fail or produce unexpected behavior depending on the OS.
| listenAddrPresetLAN: '局域网 192.168.0.0', | |
| listenAddrPresetLAN: '局域网 192.168.0.1', |
| listenAddrLabel: 'Listen address:', | ||
| listenAddrPlaceholder: 'e.g., 127.0.0.1', | ||
| listenAddrPresetPublic: 'Public 0.0.0.0', | ||
| listenAddrPresetLAN: 'LAN 192.168.0.0', |
There was a problem hiding this comment.
The preset value '192.168.0.0' is a network address, not a valid host IP to bind to. This should likely be '192.168.0.1' or another valid host address in the private range. Binding to .0.0 addresses (network addresses) may fail or produce unexpected behavior depending on the OS.
| listenAddrPresetLAN: 'LAN 192.168.0.0', | |
| listenAddrPresetLAN: 'LAN 192.168.0.1', |
| <input type="text" id="listenAddrInput" placeholder="${t('modal.listenAddrPlaceholder')}"> | ||
| <div class="listen-addr-presets"> | ||
| <button class="preset-chip" onclick="window.setListenAddrPreset('0.0.0.0')">${t('modal.listenAddrPresetPublic')}</button> | ||
| <button class="preset-chip" onclick="window.setListenAddrPreset('192.168.0.0')">${t('modal.listenAddrPresetLAN')}</button> |
There was a problem hiding this comment.
The preset value '192.168.0.0' is a network address, not a valid host IP to bind to. This should likely be '192.168.0.1' or use '0.0.0.0' to bind to all interfaces on the local machine. Network addresses ending in .0.0 are typically reserved and may not bind correctly.
| <button class="preset-chip" onclick="window.setListenAddrPreset('192.168.0.0')">${t('modal.listenAddrPresetLAN')}</button> | |
| <button class="preset-chip" onclick="window.setListenAddrPreset('192.168.0.1')">${t('modal.listenAddrPresetLAN')}</button> |
| import { t } from '../i18n/index.js'; | ||
| import { escapeHtml } from '../utils/format.js'; | ||
| import { addEndpoint, updateEndpoint, removeEndpoint, testEndpoint, testEndpointLight, updatePort } from './config.js'; | ||
| import { addEndpoint, updateEndpoint, removeEndpoint, testEndpoint, testEndpointLight, updateNetwork } from './config.js'; |
There was a problem hiding this comment.
Unused import testEndpoint.
| import { addEndpoint, updateEndpoint, removeEndpoint, testEndpoint, testEndpointLight, updateNetwork } from './config.js'; | |
| import { addEndpoint, updateEndpoint, removeEndpoint, testEndpointLight, updateNetwork } from './config.js'; |
|
@hea7enn 佬怎么看? |
|
本身就是本地代理服务,无需考虑公网问题,直接关闭吧 |
|
但是个人电脑一般也不会专门去开个公网,还提供地址给别人,这种极小概率事件 没必要还单独做个功能 ,不太实用 |

目前项目默认监听0.0.0.0公网ip且未定义auth_token 新增自定义监听地址并设置默认监听127.0.0.1 防止未经授权的公网访问

