feat(network-tweaks): Add CDN cache and WPAD proxy controls
- Add CDN cache status card with enable/disable and restart buttons - Add WPAD auto-proxy card with enable/disable toggle - Add getProxyStatus, getWpadStatus, setWpadEnabled RPCD methods - Move menu to Services section - Update ACL for CDN cache and WPAD control Also fixes: - security-threats: Fix HAProxy socket path for connection stats - tor-shield: Add missing ACL methods for excluded destinations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
aa5b8097c5
commit
dc4ec3f102
@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-network-tweaks
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
PKG_ARCH:=all
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
||||
|
||||
LUCI_TITLE:=Network Tweaks - Auto Proxy DNS & Hosts
|
||||
LUCI_DESCRIPTION:=Automatically generates DNS and hosts entries from enabled vhosts for seamless local domain resolution
|
||||
LUCI_TITLE:=Network Tweaks Dashboard
|
||||
LUCI_DESCRIPTION:=Unified network services dashboard with DNS/hosts sync, CDN cache control, and WPAD auto-proxy configuration
|
||||
LUCI_DEPENDS:=+luci-base +rpcd +luci-app-vhost-manager +dnsmasq
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
|
||||
@ -36,6 +36,32 @@ var callGetCumulativeImpact = rpc.declare({
|
||||
expect: { }
|
||||
});
|
||||
|
||||
var callCdnCacheStatus = rpc.declare({
|
||||
object: 'luci.cdn-cache',
|
||||
method: 'status',
|
||||
expect: { }
|
||||
});
|
||||
|
||||
var callCdnCacheSetEnabled = rpc.declare({
|
||||
object: 'luci.cdn-cache',
|
||||
method: 'set_enabled',
|
||||
params: ['enabled'],
|
||||
expect: { }
|
||||
});
|
||||
|
||||
var callGetWpadStatus = rpc.declare({
|
||||
object: 'luci.network-tweaks',
|
||||
method: 'getWpadStatus',
|
||||
expect: { }
|
||||
});
|
||||
|
||||
var callSetWpadEnabled = rpc.declare({
|
||||
object: 'luci.network-tweaks',
|
||||
method: 'setWpadEnabled',
|
||||
params: ['enabled'],
|
||||
expect: { }
|
||||
});
|
||||
|
||||
var callSetComponentEnabled = rpc.declare({
|
||||
object: 'luci.network-tweaks',
|
||||
method: 'setComponentEnabled',
|
||||
@ -43,7 +69,14 @@ var callSetComponentEnabled = rpc.declare({
|
||||
expect: { }
|
||||
});
|
||||
|
||||
var callGetProxyStatus = rpc.declare({
|
||||
object: 'luci.network-tweaks',
|
||||
method: 'getProxyStatus',
|
||||
expect: { }
|
||||
});
|
||||
|
||||
return view.extend({
|
||||
proxyStatusData: {},
|
||||
componentsData: [],
|
||||
cumulativeData: {},
|
||||
networkModeData: {},
|
||||
@ -60,7 +93,8 @@ return view.extend({
|
||||
return Promise.all([
|
||||
callNetworkTweaksStatus(),
|
||||
callGetNetworkComponents(),
|
||||
callGetCumulativeImpact()
|
||||
callGetCumulativeImpact(),
|
||||
callGetProxyStatus()
|
||||
]);
|
||||
},
|
||||
|
||||
@ -68,10 +102,12 @@ return view.extend({
|
||||
var status = data[0] || {};
|
||||
var componentsResponse = data[1] || {};
|
||||
var cumulativeResponse = data[2] || {};
|
||||
var proxyStatus = data[3] || {};
|
||||
|
||||
this.componentsData = componentsResponse.components || [];
|
||||
this.cumulativeData = cumulativeResponse || {};
|
||||
this.networkModeData = componentsResponse.network_mode || {};
|
||||
this.proxyStatusData = proxyStatus || {};
|
||||
|
||||
var m, s, o;
|
||||
|
||||
@ -129,6 +165,7 @@ return view.extend({
|
||||
return E('div', { 'class': 'network-tweaks-dashboard' }, [
|
||||
this.renderCumulativeImpact(),
|
||||
this.renderNetworkModeStatus(),
|
||||
this.renderProxySettings(),
|
||||
this.renderComponentsGrid(),
|
||||
this.renderSyncSection()
|
||||
]);
|
||||
@ -198,6 +235,137 @@ return view.extend({
|
||||
]);
|
||||
},
|
||||
|
||||
renderProxySettings: function() {
|
||||
var proxy = this.proxyStatusData;
|
||||
var cdnCache = proxy.cdn_cache || {};
|
||||
var wpad = proxy.wpad || {};
|
||||
|
||||
var cdnStatusClass = cdnCache.running ? 'status-running' : 'status-stopped';
|
||||
var cdnStatusText = cdnCache.running ? _('Running') : _('Stopped');
|
||||
var cdnListeningText = cdnCache.listening ?
|
||||
_('Listening on port ') + (cdnCache.port || 3128) :
|
||||
_('Not listening');
|
||||
|
||||
var wpadStatusClass = wpad.enabled ? 'status-running' : 'status-stopped';
|
||||
var wpadStatusText = wpad.enabled ? _('Enabled') : _('Disabled');
|
||||
|
||||
return E('div', { 'class': 'proxy-settings-section' }, [
|
||||
E('h3', {}, _('Proxy & Caching')),
|
||||
E('div', { 'class': 'proxy-grid', 'style': 'display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;' }, [
|
||||
// CDN Cache Card
|
||||
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [
|
||||
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [
|
||||
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [
|
||||
E('span', { 'style': 'font-size: 1.5em;' }, '\ud83d\udce6'),
|
||||
E('span', { 'style': 'font-weight: bold;' }, _('CDN Cache'))
|
||||
]),
|
||||
E('span', {
|
||||
'class': 'status-badge ' + cdnStatusClass,
|
||||
'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' +
|
||||
(cdnCache.running ? 'background: #22c55e;' : 'background: #ef4444;')
|
||||
}, cdnStatusText)
|
||||
]),
|
||||
E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [
|
||||
E('div', {}, cdnListeningText),
|
||||
E('div', {}, cdnCache.installed ? _('nginx proxy installed') : _('Not installed'))
|
||||
]),
|
||||
E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [
|
||||
E('button', {
|
||||
'class': 'btn cbi-button',
|
||||
'click': L.bind(this.handleCdnCacheToggle, this),
|
||||
'disabled': !cdnCache.installed
|
||||
}, cdnCache.enabled ? _('Disable') : _('Enable')),
|
||||
E('button', {
|
||||
'class': 'btn cbi-button',
|
||||
'click': L.bind(this.handleCdnCacheRestart, this),
|
||||
'disabled': !cdnCache.installed
|
||||
}, _('Restart'))
|
||||
])
|
||||
]),
|
||||
// WPAD Card
|
||||
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [
|
||||
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [
|
||||
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [
|
||||
E('span', { 'style': 'font-size: 1.5em;' }, '\ud83c\udf10'),
|
||||
E('span', { 'style': 'font-weight: bold;' }, _('WPAD Auto-Proxy'))
|
||||
]),
|
||||
E('span', {
|
||||
'class': 'status-badge ' + wpadStatusClass,
|
||||
'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' +
|
||||
(wpad.enabled ? 'background: #22c55e;' : 'background: #ef4444;')
|
||||
}, wpadStatusText)
|
||||
]),
|
||||
E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [
|
||||
E('div', {}, wpad.dhcp_configured ? _('DHCP Option 252 configured') : _('DHCP not configured')),
|
||||
E('div', {}, wpad.url ? wpad.url : _('No PAC URL set'))
|
||||
]),
|
||||
E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [
|
||||
E('button', {
|
||||
'class': 'btn cbi-button',
|
||||
'click': L.bind(this.handleWpadToggle, this)
|
||||
}, wpad.enabled ? _('Disable') : _('Enable'))
|
||||
])
|
||||
])
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handleCdnCacheToggle: function(ev) {
|
||||
var currentEnabled = this.proxyStatusData.cdn_cache?.enabled || false;
|
||||
var newEnabled = !currentEnabled;
|
||||
|
||||
ui.showModal(_('Updating...'), [
|
||||
E('p', { 'class': 'spinning' }, _('Please wait...'))
|
||||
]);
|
||||
|
||||
return callCdnCacheSetEnabled(newEnabled ? 1 : 0).then(L.bind(function() {
|
||||
ui.hideModal();
|
||||
this.refreshData();
|
||||
}, this)).catch(function(err) {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', _('Error: ') + err.message), 'error');
|
||||
});
|
||||
},
|
||||
|
||||
handleCdnCacheRestart: function(ev) {
|
||||
ui.showModal(_('Restarting...'), [
|
||||
E('p', { 'class': 'spinning' }, _('Please wait...'))
|
||||
]);
|
||||
|
||||
return rpc.declare({
|
||||
object: 'luci.cdn-cache',
|
||||
method: 'restart',
|
||||
expect: { }
|
||||
})().then(L.bind(function() {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', _('CDN Cache restarted')), 'info');
|
||||
this.refreshData();
|
||||
}, this)).catch(function(err) {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', _('Error: ') + err.message), 'error');
|
||||
});
|
||||
},
|
||||
|
||||
handleWpadToggle: function(ev) {
|
||||
var currentEnabled = this.proxyStatusData.wpad?.enabled || false;
|
||||
var newEnabled = !currentEnabled;
|
||||
|
||||
ui.showModal(_('Updating...'), [
|
||||
E('p', { 'class': 'spinning' }, _('Please wait...'))
|
||||
]);
|
||||
|
||||
return callSetWpadEnabled(newEnabled ? 1 : 0).then(L.bind(function(result) {
|
||||
ui.hideModal();
|
||||
if (result.success) {
|
||||
ui.addNotification(null, E('p', result.message || _('WPAD updated')), 'info');
|
||||
}
|
||||
this.refreshData();
|
||||
}, this)).catch(function(err) {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', _('Error: ') + err.message), 'error');
|
||||
});
|
||||
},
|
||||
|
||||
renderComponentsGrid: function() {
|
||||
var components = this.componentsData;
|
||||
|
||||
@ -362,14 +530,17 @@ return view.extend({
|
||||
refreshData: function() {
|
||||
return Promise.all([
|
||||
callGetNetworkComponents(),
|
||||
callGetCumulativeImpact()
|
||||
callGetCumulativeImpact(),
|
||||
callGetProxyStatus()
|
||||
]).then(L.bind(function(data) {
|
||||
var componentsResponse = data[0] || {};
|
||||
var cumulativeResponse = data[1] || {};
|
||||
var proxyStatus = data[2] || {};
|
||||
|
||||
this.componentsData = componentsResponse.components || [];
|
||||
this.cumulativeData = cumulativeResponse || {};
|
||||
this.networkModeData = componentsResponse.network_mode || {};
|
||||
this.proxyStatusData = proxyStatus || {};
|
||||
|
||||
this.updateDisplay();
|
||||
}, this));
|
||||
@ -383,6 +554,7 @@ return view.extend({
|
||||
dom.content(dashboard, [
|
||||
this.renderCumulativeImpact(),
|
||||
this.renderNetworkModeStatus(),
|
||||
this.renderProxySettings(),
|
||||
this.renderComponentsGrid(),
|
||||
this.renderSyncSection()
|
||||
]);
|
||||
|
||||
@ -284,6 +284,13 @@ case "$1" in
|
||||
json_add_string "app_id" "string"
|
||||
json_add_string "enabled" "boolean"
|
||||
json_close_object
|
||||
json_add_object "getWpadStatus"
|
||||
json_close_object
|
||||
json_add_object "setWpadEnabled"
|
||||
json_add_string "enabled" "boolean"
|
||||
json_close_object
|
||||
json_add_object "getProxyStatus"
|
||||
json_close_object
|
||||
json_dump
|
||||
;;
|
||||
|
||||
@ -465,6 +472,166 @@ case "$1" in
|
||||
json_dump
|
||||
;;
|
||||
|
||||
getWpadStatus)
|
||||
# Get WPAD/PAC file status
|
||||
json_init
|
||||
json_add_boolean "success" 1
|
||||
|
||||
# Check if WPAD file exists
|
||||
wpad_enabled=0
|
||||
wpad_file=""
|
||||
if [ -f /www/wpad.dat ]; then
|
||||
wpad_enabled=1
|
||||
wpad_file="/www/wpad.dat"
|
||||
fi
|
||||
|
||||
# Check DHCP option 252 configuration
|
||||
dhcp_wpad_enabled=0
|
||||
config_load dhcp
|
||||
check_dhcp_option() {
|
||||
local value
|
||||
config_get value "$1" "252"
|
||||
[ -n "$value" ] && dhcp_wpad_enabled=1
|
||||
}
|
||||
config_foreach check_dhcp_option dhcp
|
||||
|
||||
# Check dnsmasq wpad entry
|
||||
dns_wpad_enabled=0
|
||||
if grep -q "wpad" /etc/hosts 2>/dev/null || \
|
||||
grep -q "wpad" /tmp/hosts.vhosts 2>/dev/null; then
|
||||
dns_wpad_enabled=1
|
||||
fi
|
||||
|
||||
json_add_object "wpad"
|
||||
json_add_boolean "enabled" "$wpad_enabled"
|
||||
json_add_string "file" "$wpad_file"
|
||||
json_add_boolean "dhcp_configured" "$dhcp_wpad_enabled"
|
||||
json_add_boolean "dns_configured" "$dns_wpad_enabled"
|
||||
json_close_object
|
||||
|
||||
json_dump
|
||||
;;
|
||||
|
||||
setWpadEnabled)
|
||||
# Enable/disable WPAD
|
||||
read input
|
||||
json_load "$input"
|
||||
|
||||
json_get_var enabled enabled
|
||||
|
||||
if [ "$enabled" = "1" ] || [ "$enabled" = "true" ]; then
|
||||
# Get LAN IP
|
||||
lan_ip=$(uci get network.lan.ipaddr 2>/dev/null | cut -d'/' -f1)
|
||||
[ -z "$lan_ip" ] && lan_ip="192.168.255.1"
|
||||
|
||||
# Create WPAD/PAC file
|
||||
cat > /www/wpad.dat << EOF
|
||||
function FindProxyForURL(url, host) {
|
||||
// Direct access for local network
|
||||
if (isInNet(host, "192.168.0.0", "255.255.0.0") ||
|
||||
isInNet(host, "10.0.0.0", "255.0.0.0") ||
|
||||
isInNet(host, "172.16.0.0", "255.240.0.0") ||
|
||||
shExpMatch(host, "*.local") ||
|
||||
shExpMatch(host, "*.lan")) {
|
||||
return "DIRECT";
|
||||
}
|
||||
// Use CDN Cache proxy for everything else
|
||||
return "PROXY ${lan_ip}:3128; DIRECT";
|
||||
}
|
||||
EOF
|
||||
chmod 644 /www/wpad.dat
|
||||
|
||||
# Add DHCP option 252 for WPAD discovery
|
||||
uci set dhcp.lan.dhcp_option_force="252,http://${lan_ip}/wpad.dat"
|
||||
uci commit dhcp
|
||||
|
||||
# Add wpad DNS entry
|
||||
if ! grep -q "wpad" /etc/hosts 2>/dev/null; then
|
||||
echo "${lan_ip} wpad wpad.lan" >> /etc/hosts
|
||||
fi
|
||||
|
||||
# Restart dnsmasq
|
||||
/etc/init.d/dnsmasq reload >/dev/null 2>&1
|
||||
|
||||
json_init
|
||||
json_add_boolean "success" 1
|
||||
json_add_string "message" "WPAD enabled"
|
||||
else
|
||||
# Remove WPAD file
|
||||
rm -f /www/wpad.dat
|
||||
|
||||
# Remove DHCP option
|
||||
uci delete dhcp.lan.dhcp_option_force 2>/dev/null
|
||||
uci commit dhcp
|
||||
|
||||
# Remove wpad DNS entry
|
||||
sed -i '/wpad/d' /etc/hosts 2>/dev/null
|
||||
|
||||
# Restart dnsmasq
|
||||
/etc/init.d/dnsmasq reload >/dev/null 2>&1
|
||||
|
||||
json_init
|
||||
json_add_boolean "success" 1
|
||||
json_add_string "message" "WPAD disabled"
|
||||
fi
|
||||
|
||||
json_dump
|
||||
;;
|
||||
|
||||
getProxyStatus)
|
||||
# Get comprehensive proxy status (CDN Cache + WPAD)
|
||||
json_init
|
||||
json_add_boolean "success" 1
|
||||
|
||||
# CDN Cache status
|
||||
cdn_running=0
|
||||
cdn_enabled=0
|
||||
cdn_port=3128
|
||||
|
||||
if [ -x /etc/init.d/cdn-cache ]; then
|
||||
/etc/init.d/cdn-cache running >/dev/null 2>&1 && cdn_running=1
|
||||
cdn_enabled=$(uci get cdn-cache.main.enabled 2>/dev/null)
|
||||
[ -z "$cdn_enabled" ] && cdn_enabled=0
|
||||
cdn_port=$(uci get cdn-cache.main.listen_port 2>/dev/null)
|
||||
[ -z "$cdn_port" ] && cdn_port=3128
|
||||
fi
|
||||
|
||||
# Check if port is actually listening
|
||||
cdn_listening=0
|
||||
if netstat -tln 2>/dev/null | grep -q ":${cdn_port}"; then
|
||||
cdn_listening=1
|
||||
fi
|
||||
|
||||
json_add_object "cdn_cache"
|
||||
json_add_boolean "installed" "$([ -x /etc/init.d/cdn-cache ] && echo 1 || echo 0)"
|
||||
json_add_boolean "enabled" "$cdn_enabled"
|
||||
json_add_boolean "running" "$cdn_running"
|
||||
json_add_boolean "listening" "$cdn_listening"
|
||||
json_add_int "port" "$cdn_port"
|
||||
json_close_object
|
||||
|
||||
# WPAD status
|
||||
wpad_enabled=0
|
||||
[ -f /www/wpad.dat ] && wpad_enabled=1
|
||||
|
||||
dhcp_wpad=0
|
||||
wpad_url=""
|
||||
config_load dhcp
|
||||
wpad_opt=$(uci get dhcp.lan.dhcp_option_force 2>/dev/null)
|
||||
if echo "$wpad_opt" | grep -q "252"; then
|
||||
dhcp_wpad=1
|
||||
wpad_url=$(echo "$wpad_opt" | sed 's/252,//')
|
||||
fi
|
||||
|
||||
json_add_object "wpad"
|
||||
json_add_boolean "enabled" "$wpad_enabled"
|
||||
json_add_boolean "dhcp_configured" "$dhcp_wpad"
|
||||
json_add_string "url" "$wpad_url"
|
||||
json_close_object
|
||||
|
||||
json_dump
|
||||
;;
|
||||
|
||||
*)
|
||||
json_init
|
||||
json_add_boolean "success" 0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"admin/secubox/network/tweaks": {
|
||||
"admin/services/network-tweaks": {
|
||||
"title": "Network Tweaks",
|
||||
"order": 50,
|
||||
"order": 80,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "network-tweaks/overview"
|
||||
|
||||
@ -3,15 +3,17 @@
|
||||
"description": "Grant access to Network Tweaks",
|
||||
"read": {
|
||||
"ubus": {
|
||||
"luci.network-tweaks": ["getStatus", "getConfig", "getNetworkComponents", "getCumulativeImpact"]
|
||||
"luci.network-tweaks": ["getStatus", "getConfig", "getNetworkComponents", "getCumulativeImpact", "getWpadStatus", "getProxyStatus"],
|
||||
"luci.cdn-cache": ["status", "stats"]
|
||||
},
|
||||
"uci": ["network_tweaks", "vhosts"]
|
||||
"uci": ["network_tweaks", "vhosts", "cdn-cache", "dhcp"]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"luci.network-tweaks": ["syncNow", "setConfig", "setComponentEnabled"]
|
||||
"luci.network-tweaks": ["syncNow", "setConfig", "setComponentEnabled", "setWpadEnabled"],
|
||||
"luci.cdn-cache": ["set_enabled", "restart"]
|
||||
},
|
||||
"uci": ["network_tweaks"]
|
||||
"uci": ["network_tweaks", "dhcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-secubox-security-threats
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=2
|
||||
PKG_RELEASE:=3
|
||||
PKG_ARCH:=all
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
||||
|
||||
@ -321,7 +321,12 @@ get_security_stats() {
|
||||
|
||||
# HAProxy connections (if running in LXC)
|
||||
if lxc-info -n haproxy -s 2>/dev/null | grep -q "RUNNING"; then
|
||||
haproxy_conns=$(lxc-attach -n haproxy -- sh -c 'echo "show stat" | socat stdio /var/run/haproxy/admin.sock 2>/dev/null | tail -n+2 | awk -F, "{sum+=\$8} END {print sum}"' 2>/dev/null || echo 0)
|
||||
# Try multiple socket paths (chroot-relative and absolute)
|
||||
haproxy_conns=$(lxc-attach -n haproxy -- sh -c '
|
||||
for sock in /stats /run/haproxy.sock /var/lib/haproxy/stats /var/run/haproxy/admin.sock; do
|
||||
[ -S "$sock" ] && echo "show stat" | socat stdio "$sock" 2>/dev/null && break
|
||||
done | tail -n+2 | awk -F, "{sum+=\$5} END {print sum+0}"
|
||||
' 2>/dev/null || echo 0)
|
||||
fi
|
||||
haproxy_conns=$(echo "$haproxy_conns" | tr -d '\n')
|
||||
haproxy_conns=${haproxy_conns:-0}
|
||||
|
||||
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-tor-shield
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
PKG_ARCH:=all
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
"bandwidth",
|
||||
"presets",
|
||||
"bridges",
|
||||
"settings"
|
||||
"settings",
|
||||
"excluded_destinations",
|
||||
"refresh_ips"
|
||||
],
|
||||
"system": [ "info", "board" ],
|
||||
"file": [ "read", "stat", "exec" ]
|
||||
@ -35,7 +37,10 @@
|
||||
"add_hidden_service",
|
||||
"remove_hidden_service",
|
||||
"set_bridges",
|
||||
"save_settings"
|
||||
"save_settings",
|
||||
"add_excluded_destination",
|
||||
"remove_excluded_destination",
|
||||
"apply_exclusions"
|
||||
]
|
||||
},
|
||||
"uci": [ "tor-shield" ],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user