mirror of
https://github.com/coolsnowwolf/packages.git
synced 2025-05-01 06:11:25 +08:00
packages: sync with 19.07-rc2
This commit is contained in:
parent
13f3fbaedb
commit
eeea03f457
65
net/banip/Makefile
Normal file
65
net/banip/Makefile
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2018-2019 Dirk Brenken (dev@brenken.org)
|
||||||
|
# This is free software, licensed under the GNU General Public License v3.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=banip
|
||||||
|
PKG_VERSION:=0.3.10
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
PKG_LICENSE:=GPL-3.0-or-later
|
||||||
|
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/banip
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
TITLE:=Ban incoming and/or outgoing ip adresses via ipsets
|
||||||
|
DEPENDS:=+jshn +jsonfilter +ip +ipset +iptables +ca-bundle +logd
|
||||||
|
PKGARCH:=all
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/banip/description
|
||||||
|
Powerful banIP script to block ip addresses via ipsets.
|
||||||
|
The script supports many ip blacklist sites plus manual black- and whitelist overrides.
|
||||||
|
Please see https://github.com/openwrt/packages/blob/master/net/banip/files/README.md for further information.
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/banip/conffiles
|
||||||
|
/etc/config/banip
|
||||||
|
/etc/banip/banip.whitelist
|
||||||
|
/etc/banip/banip.blacklist
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Configure
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/banip/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
|
$(INSTALL_BIN) ./files/banip.sh $(1)/usr/bin
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/banip.init $(1)/etc/init.d/banip
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_CONF) ./files/banip.conf $(1)/etc/config/banip
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/banip
|
||||||
|
$(INSTALL_BIN) ./files/banip.service $(1)/etc/banip
|
||||||
|
$(INSTALL_CONF) ./files/banip.blacklist $(1)/etc/banip
|
||||||
|
$(INSTALL_CONF) ./files/banip.whitelist $(1)/etc/banip
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/hotplug.d/firewall
|
||||||
|
$(INSTALL_DATA) ./files/banip.hotplug $(1)/etc/hotplug.d/firewall/30-banip
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,banip))
|
96
net/banip/files/README.md
Normal file
96
net/banip/files/README.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# banIP - ban incoming and/or outgoing ip adresses via ipsets
|
||||||
|
|
||||||
|
## Description
|
||||||
|
IP address blocking is commonly used to protect against brute force attacks, prevent disruptive or unauthorized address(es) from access or it can be used to restrict access to or from a particular geographic area — for example.
|
||||||
|
|
||||||
|
## Main Features
|
||||||
|
* support many IP blocklist sources (free for private usage, for commercial use please check their individual licenses):
|
||||||
|
* zero-conf like automatic installation & setup, usually no manual changes needed
|
||||||
|
* automatically selects one of the following download utilities: aria2c, curl, uclient-fetch, wget
|
||||||
|
* Really fast downloads & list processing as they are handled in parallel as background jobs in a configurable 'Download Queue'
|
||||||
|
* full IPv4 and IPv6 support
|
||||||
|
* ipsets (one per source) are used to ban a large number of IP addresses
|
||||||
|
* supports blocking by ASN numbers
|
||||||
|
* supports blocking by iso country codes
|
||||||
|
* supports local white & blacklist (IPv4, IPv6 & CIDR notation), located by default in /etc/banip/banip.whitelist and /etc/banip/banip.blacklist
|
||||||
|
* auto-add unsuccessful LuCI and ssh login attempts via 'dropbear' or 'sshd' to local blacklist (see 'ban_autoblacklist' option)
|
||||||
|
* auto-add the uplink subnet to local whitelist (see 'ban_autowhitelist' option)
|
||||||
|
* provides a small background log monitor to ban unsuccessful login attempts in real-time
|
||||||
|
* per source configuration of SRC (incoming) and DST (outgoing)
|
||||||
|
* integrated IPSet-Lookup
|
||||||
|
* integrated RIPE-Lookup
|
||||||
|
* blocklist source parsing by fast & flexible regex rulesets
|
||||||
|
* minimal status & error logging to syslog, enable debug logging to receive more output
|
||||||
|
* procd based init system support (start/stop/restart/reload/refresh/status)
|
||||||
|
* procd network interface trigger support
|
||||||
|
* automatic blocklist backup & restore, they will be used in case of download errors or during startup
|
||||||
|
* output comprehensive runtime information via LuCI or via 'status' init command
|
||||||
|
* strong LuCI support
|
||||||
|
* optional: add new banIP sources on your own
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
* [OpenWrt](https://openwrt.org), tested with the stable release series (19.07) and with the latest snapshot
|
||||||
|
* download utility: 'uclient-fetch' with one of the 'libustream-*' ssl libraries, 'wget', 'aria2c' or 'curl' is required
|
||||||
|
|
||||||
|
## Installation & Usage
|
||||||
|
* install 'banip' (_opkg install banip_)
|
||||||
|
* at minimum configure the needed IP blocklist sources, the download utility and enable the banIP service in _/etc/config/banip_
|
||||||
|
* control the banip service manually with _/etc/init.d/banip_ start/stop/restart/reload/refresh/status or use the LuCI frontend
|
||||||
|
|
||||||
|
## LuCI banIP companion package
|
||||||
|
* it's recommended to use the provided LuCI frontend to control all aspects of banIP
|
||||||
|
* install 'luci-app-banip' (_opkg install luci-app-banip_)
|
||||||
|
* the application is located in LuCI under 'Services' menu
|
||||||
|
|
||||||
|
## banIP config options
|
||||||
|
* usually the pre-configured banIP setup works quite well and no manual overrides are needed
|
||||||
|
* the following options apply to the 'global' config section:
|
||||||
|
* ban\_enabled => main switch to enable/disable banIP service (bool/default: '0', disabled)
|
||||||
|
* ban\_automatic => determine the L2/L3 WAN network device automatically (bool/default: '1', enabled)
|
||||||
|
* ban\_iface => space separated list of WAN network interface(s)/device(s) used by banIP (default: not set, automatically detected)
|
||||||
|
* ban\_realtime => a small log/banIP background monitor to block SSH/LuCI brute force attacks in realtime (bool/default: 'false', disabled)
|
||||||
|
|
||||||
|
* the following options apply to the 'extra' config section:
|
||||||
|
* ban\_debug => enable/disable banIP debug output (bool/default: '0', disabled)
|
||||||
|
* ban\_nice => set the nice level of the banIP process and all sub-processes (int/default: '0', standard priority)
|
||||||
|
* ban\_triggerdelay => additional trigger delay in seconds before banIP processing begins (int/default: '2')
|
||||||
|
* ban\_backupdir => target directory for banIP backups (default: '/tmp')
|
||||||
|
* ban\_sshdaemon => select the SSH daemon for logfile parsing, 'dropbear' or 'sshd' (default: 'dropbear')
|
||||||
|
* ban\_starttype => select the used start type during boot, 'start', 'refresh' or 'reload' (default: 'start')
|
||||||
|
* ban\_maxqueue => size of the download queue to handle downloads & IPSet processing in parallel (int/default: '4')
|
||||||
|
* ban\_fetchutil => name of the used download utility: 'uclient-fetch', 'wget', 'curl', 'aria2c' (default: not set, automatically detected)
|
||||||
|
* ban\_fetchparm => special config options for the download utility (default: not set)
|
||||||
|
* ban\_autoblacklist => store auto-addons temporary in ipset and permanently in local blacklist as well (bool/default: '1', enabled)
|
||||||
|
* ban\_autowhitelist => store auto-addons temporary in ipset and permanently in local whitelist as well (bool/default: '1', enabled)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
**receive banIP runtime information:**
|
||||||
|
|
||||||
|
<pre><code>
|
||||||
|
/etc/init.d/banip status
|
||||||
|
::: banIP runtime information
|
||||||
|
+ status : enabled
|
||||||
|
+ version : 0.3.0
|
||||||
|
+ util_info : /usr/bin/aria2c, true
|
||||||
|
+ ipset_info : 10 IPSets with overall 106729 IPs/Prefixes
|
||||||
|
+ backup_dir : /tmp
|
||||||
|
+ last_run : 03.10.2019 19:15:25
|
||||||
|
+ system : UBNT-ERX, OpenWrt SNAPSHOT r11102-ced4c0e635
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
**cronjob for a regular IPSet blocklist update (/etc/crontabs/root):**
|
||||||
|
|
||||||
|
<pre><code>
|
||||||
|
0 06 * * * /etc/init.d/banip reload
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
|
||||||
|
## Support
|
||||||
|
Please join the banIP discussion in this [forum thread](https://forum.openwrt.org/t/banip-support-thread/16985) or contact me by mail <dev@brenken.org>
|
||||||
|
|
||||||
|
## Removal
|
||||||
|
* stop all banIP related services with _/etc/init.d/banip stop_
|
||||||
|
* optional: remove the banip package (_opkg remove banip_)
|
||||||
|
|
||||||
|
Have fun!
|
||||||
|
Dirk
|
0
net/banip/files/banip.blacklist
Normal file
0
net/banip/files/banip.blacklist
Normal file
224
net/banip/files/banip.conf
Normal file
224
net/banip/files/banip.conf
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
|
||||||
|
config banip 'global'
|
||||||
|
option ban_enabled '0'
|
||||||
|
option ban_basever '0.3'
|
||||||
|
option ban_automatic '1'
|
||||||
|
option ban_realtime 'false'
|
||||||
|
|
||||||
|
config banip 'extra'
|
||||||
|
option ban_debug '0'
|
||||||
|
option ban_maxqueue '4'
|
||||||
|
|
||||||
|
config source 'whitelist'
|
||||||
|
option ban_src '/etc/banip/banip.whitelist'
|
||||||
|
option ban_src_6 '/etc/banip/banip.whitelist'
|
||||||
|
option ban_src_desc 'Always allow these IPs (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add whitelist \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add whitelist_6 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src+dst'
|
||||||
|
option ban_src_on '1'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'blacklist'
|
||||||
|
option ban_src '/etc/banip/banip.blacklist'
|
||||||
|
option ban_src_6 '/etc/banip/banip.blacklist'
|
||||||
|
option ban_src_desc 'Always deny these IPs (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add blacklist \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add blacklist_6 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src+dst'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'bogon'
|
||||||
|
option ban_src 'https://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt'
|
||||||
|
option ban_src_6 'https://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt'
|
||||||
|
option ban_src_desc 'Bogon prefixes, plus prefixes that have been allocated to RIRs but not yet assigned to ISPs (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add bogon \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add bogon_6 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src+dst'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'DoH'
|
||||||
|
option ban_src 'https://raw.githubusercontent.com/dibdot/DoH-IP-blocklists/master/doh-ipv4.txt'
|
||||||
|
option ban_src_6 'https://raw.githubusercontent.com/dibdot/DoH-IP-blocklists/master/doh-ipv6.txt'
|
||||||
|
option ban_src_desc 'List of public DoH providers (DNS over HTTPS) (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add DoH \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add DoH_6 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src+dst'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'tor'
|
||||||
|
option ban_src 'https://check.torproject.org/exit-addresses'
|
||||||
|
option ban_src_desc 'List of Tor Exit Nodes (IPv4)'
|
||||||
|
option ban_src_rset '/^(ExitAddress ([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add tor \"\$2}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'threat'
|
||||||
|
option ban_src 'https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt'
|
||||||
|
option ban_src_desc 'Emerging Threats (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add threat \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'debl'
|
||||||
|
option ban_src 'https://www.blocklist.de/downloads/export-ips_all.txt'
|
||||||
|
option ban_src_6 'https://www.blocklist.de/downloads/export-ips_all.txt'
|
||||||
|
option ban_src_desc 'Fail2ban reporting service (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add debl \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add debl_6 \"\$1}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'myip'
|
||||||
|
option ban_src 'https://www.myip.ms/files/blacklist/general/latest_blacklist.txt'
|
||||||
|
option ban_src_6 'https://www.myip.ms/files/blacklist/general/latest_blacklist.txt'
|
||||||
|
option ban_src_desc 'IP blacklist provided by myip.ms (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add myip \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add myip_6 \"\$1}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'yoyo'
|
||||||
|
option ban_src 'https://pgl.yoyo.org/adservers/iplist.php?ipformat=plain&showintro=0&mimetype=plaintext'
|
||||||
|
option ban_src_desc 'IP blocklist provided by Peter Lowe (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add yoyo \"\$1}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'sslbl'
|
||||||
|
option ban_src 'https://sslbl.abuse.ch/blacklist/sslipblacklist.csv'
|
||||||
|
option ban_src_desc 'SSL Blacklist by abuse.ch (IPv4)'
|
||||||
|
option ban_src_rset 'BEGIN{FS=\",\"}/(([0-9]{1,3}\.){3}[0-9]{1,3},).*/{print \"add sslbl \"\$2}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'ransomware'
|
||||||
|
option ban_src 'https://ransomwaretracker.abuse.ch/downloads/RW_IPBL.txt'
|
||||||
|
option ban_src_desc 'Ransomware Tracker by abuse.ch (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add ransomware \"\$1}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'feodo'
|
||||||
|
option ban_src 'https://feodotracker.abuse.ch/downloads/ipblocklist.txt'
|
||||||
|
option ban_src_desc 'Feodo Tracker by abuse.ch (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add feodo \"\$1}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'dshield'
|
||||||
|
option ban_src 'https://feeds.dshield.org/block.txt'
|
||||||
|
option ban_src_desc 'Dshield recommended IP blocklist. Contains top 20 attacking class C subnets (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add dshield \"\$1 \"/\"\$3}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'proxy'
|
||||||
|
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/proxylists.ipset'
|
||||||
|
option ban_src_desc 'List of Open Proxies (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3})([[:space:]]|$)/{print \"add proxy \"\$1}'
|
||||||
|
option ban_src_settype 'ip'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'iblocklist'
|
||||||
|
option ban_src 'https://list.iblocklist.com/?list=dgxtneitpuvgqqcpfulq&fileformat=cidr&archiveformat=gz'
|
||||||
|
option ban_src_desc 'Contains advertising trackers and a short list of bad/intrusive porn sites (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add iblocklist \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'drop'
|
||||||
|
option ban_src 'https://www.spamhaus.org/drop/drop.txt'
|
||||||
|
option ban_src_6 'https://www.spamhaus.org/drop/dropv6.txt'
|
||||||
|
option ban_src_desc 'Spamhaus drop compilation (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add drop \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add drop_6 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'edrop'
|
||||||
|
option ban_src 'https://www.spamhaus.org/drop/edrop.txt'
|
||||||
|
option ban_src_desc 'Spamhaus edrop compilation (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add edrop \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'firehol1'
|
||||||
|
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset'
|
||||||
|
option ban_src_desc 'Firehol Level 1 compilation. Contains bogons, spamhaus drop and edrop, dshield and malware lists (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol1 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'firehol2'
|
||||||
|
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level2.netset'
|
||||||
|
option ban_src_desc 'Firehol Level 2 compilation. Contains blocklists that track attacks, during the last 48 hours (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol2 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'firehol3'
|
||||||
|
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level3.netset'
|
||||||
|
option ban_src_desc 'Firehol Level 3 compilation. Contains blocklists that track attacks, spyware and viruses (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol3 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'firehol4'
|
||||||
|
option ban_src 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level4.netset'
|
||||||
|
option ban_src_desc 'Firehol Level 4 compilation. May include a large number of false positives (IPv4)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add firehol4 \"\$1}'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
|
||||||
|
config source 'country'
|
||||||
|
option ban_src 'https://stat.ripe.net/data/country-resource-list/data.json?resource='
|
||||||
|
option ban_src_6 'https://stat.ripe.net/data/country-resource-list/data.json?resource='
|
||||||
|
option ban_src_desc 'Build a dynamic IPSet by country iso codes based on RIPE data (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add country \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add country_6 \"\$1}'
|
||||||
|
list ban_src_cat 'de'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
||||||
|
|
||||||
|
config source 'asn'
|
||||||
|
option ban_src 'https://stat.ripe.net/data/announced-prefixes/data.json?resource='
|
||||||
|
option ban_src_6 'https://stat.ripe.net/data/announced-prefixes/data.json?resource='
|
||||||
|
option ban_src_desc 'Build a dynamic IPSet by ASN numbers based on RIPE data (IPv4/IPv6)'
|
||||||
|
option ban_src_rset '/^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?)([[:space:]]|$)/{print \"add asn \"\$1}'
|
||||||
|
option ban_src_rset_6 '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(:\/[0-9]{1,2})?([[:space:]]|$)/{print \"add asn_6 \"\$1}'
|
||||||
|
list ban_src_cat '32934'
|
||||||
|
option ban_src_settype 'net'
|
||||||
|
option ban_src_ruletype 'src'
|
||||||
|
option ban_src_on '0'
|
||||||
|
option ban_src_on_6 '0'
|
15
net/banip/files/banip.hotplug
Normal file
15
net/banip/files/banip.hotplug
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
[ "${ACTION}" != "add" ] && exit 0
|
||||||
|
|
||||||
|
ban_iface="wan"
|
||||||
|
[ -r "/lib/functions/network.sh" ] && { . "/lib/functions/network.sh"; network_find_wan ban_iface; }
|
||||||
|
[ "${INTERFACE}" != "${ban_iface}" ] && exit 0
|
||||||
|
|
||||||
|
ban_pidfile="/var/run/banip.pid"
|
||||||
|
ban_enabled="$(/etc/init.d/banip enabled; printf "%u" "${?}")"
|
||||||
|
if [ "${ban_enabled}" = "0" ] && [ ! -s "${ban_pidfile}" ]
|
||||||
|
then
|
||||||
|
/etc/init.d/banip refresh
|
||||||
|
fi
|
||||||
|
exit 0
|
109
net/banip/files/banip.init
Executable file
109
net/banip/files/banip.init
Executable file
@ -0,0 +1,109 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
#
|
||||||
|
|
||||||
|
START=30
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
EXTRA_COMMANDS="refresh"
|
||||||
|
EXTRA_HELP=" refresh Refresh ipsets without new list downloads"
|
||||||
|
|
||||||
|
ban_init="/etc/init.d/banip"
|
||||||
|
ban_script="/usr/bin/banip.sh"
|
||||||
|
ban_pidfile="/var/run/banip.pid"
|
||||||
|
|
||||||
|
if [ -s "${ban_pidfile}" ] && { [ "${action}" = "start" ] || [ "${action}" = "stop" ] || \
|
||||||
|
[ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "refresh" ]; }
|
||||||
|
then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
boot()
|
||||||
|
{
|
||||||
|
[ -s "${ban_pidfile}" ] && > "${ban_pidfile}"
|
||||||
|
rc_procd start_service
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service()
|
||||||
|
{
|
||||||
|
if [ "$("${ban_init}" enabled; printf "%u" ${?})" -eq 0 ]
|
||||||
|
then
|
||||||
|
if [ "${action}" = "boot" ]
|
||||||
|
then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
procd_open_instance "banip"
|
||||||
|
procd_set_param command "${ban_script}" "${@}"
|
||||||
|
procd_set_param pidfile "${ban_pidfile}"
|
||||||
|
procd_set_param nice "$(uci_get banip extra ban_nice "0")"
|
||||||
|
procd_set_param stdout 1
|
||||||
|
procd_set_param stderr 1
|
||||||
|
procd_close_instance
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh()
|
||||||
|
{
|
||||||
|
rc_procd start_service refresh
|
||||||
|
}
|
||||||
|
|
||||||
|
reload_service()
|
||||||
|
{
|
||||||
|
rc_procd start_service reload
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service()
|
||||||
|
{
|
||||||
|
rc_procd "${ban_script}" stop
|
||||||
|
}
|
||||||
|
|
||||||
|
restart()
|
||||||
|
{
|
||||||
|
rc_procd start_service restart
|
||||||
|
}
|
||||||
|
|
||||||
|
status_service()
|
||||||
|
{
|
||||||
|
local key keylist value
|
||||||
|
local rtfile="$(uci_get banip global ban_rtfile "/tmp/ban_runtime.json")"
|
||||||
|
|
||||||
|
json_load_file "${rtfile}" >/dev/null 2>&1
|
||||||
|
json_select data >/dev/null 2>&1
|
||||||
|
if [ "${?}" -eq 0 ]
|
||||||
|
then
|
||||||
|
printf "%s\\n" "::: banIP runtime information"
|
||||||
|
json_get_keys keylist
|
||||||
|
for key in ${keylist}
|
||||||
|
do
|
||||||
|
json_get_var value "${key}"
|
||||||
|
printf " + %-10s : %s\\n" "${key}" "${value}"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
printf "%s\\n" "::: no banIP runtime information available"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
service_triggers()
|
||||||
|
{
|
||||||
|
local trigger trigger_list="$(uci_get banip global ban_trigger)"
|
||||||
|
local delay="$(uci_get banip extra ban_triggerdelay "2")"
|
||||||
|
local type="$(uci_get banip extra ban_starttype "start")"
|
||||||
|
|
||||||
|
PROCD_RELOAD_DELAY=$((${delay}*1000))
|
||||||
|
|
||||||
|
if [ -z "${trigger_list}" ] && [ -r "/lib/functions/network.sh" ]
|
||||||
|
then
|
||||||
|
. "/lib/functions/network.sh"
|
||||||
|
network_find_wan trigger_list
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${trigger_list}" ]
|
||||||
|
then
|
||||||
|
for trigger in ${trigger_list}
|
||||||
|
do
|
||||||
|
procd_add_interface_trigger "interface.*.up" "${trigger}" "${ban_init}" "${type}"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
procd_add_raw_trigger "interface.*.up" ${PROCD_RELOAD_DELAY} "${ban_init}" "${type}"
|
||||||
|
fi
|
||||||
|
procd_add_reload_trigger "banip"
|
||||||
|
}
|
35
net/banip/files/banip.service
Executable file
35
net/banip/files/banip.service
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# log service to trace failed ssh/luci logins and conditionally refresh banIP
|
||||||
|
# written by Dirk Brenken (dev@brenken.org)
|
||||||
|
|
||||||
|
# This is free software, licensed under the GNU General Public License v3.
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
ban_ver="${1}"
|
||||||
|
ban_sshdaemon="${2}"
|
||||||
|
ban_logger="$(command -v logger)"
|
||||||
|
ban_logread="$(command -v logread)"
|
||||||
|
|
||||||
|
f_log()
|
||||||
|
{
|
||||||
|
local class="${1}" log_msg="${2}"
|
||||||
|
|
||||||
|
if [ -x "${ban_logger}" ]
|
||||||
|
then
|
||||||
|
"${ban_logger}" -p "${class}" -t "banIP-${ban_ver}[${$}]" "${log_msg}"
|
||||||
|
else
|
||||||
|
printf "%s %s %s\\n" "${class}" "banIP-${ban_ver}[${$}]" "${log_msg}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -x "${ban_logread}" ]
|
||||||
|
then
|
||||||
|
f_log "info" "log/banIP service started"
|
||||||
|
"${ban_logread}" -f -e "${ban_sshdaemon}\|luci: failed login" | \
|
||||||
|
{ grep -qE "Exit before auth|luci: failed login|[0-9]+ \[preauth\]$"; [ $? -eq 0 ] && /etc/init.d/banip refresh; }
|
||||||
|
else
|
||||||
|
f_log "err" "can't start log/banIP service"
|
||||||
|
fi
|
958
net/banip/files/banip.sh
Executable file
958
net/banip/files/banip.sh
Executable file
@ -0,0 +1,958 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# banIP - ban incoming and outgoing ip adresses/subnets via ipset
|
||||||
|
# written by Dirk Brenken (dev@brenken.org)
|
||||||
|
|
||||||
|
# This is free software, licensed under the GNU General Public License v3.
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# (s)hellcheck exceptions
|
||||||
|
# shellcheck disable=1091 disable=2039 disable=2143 disable=2181 disable=2188
|
||||||
|
|
||||||
|
# set initial defaults
|
||||||
|
#
|
||||||
|
LC_ALL=C
|
||||||
|
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
ban_ver="0.3.10"
|
||||||
|
ban_basever=""
|
||||||
|
ban_enabled=0
|
||||||
|
ban_automatic="1"
|
||||||
|
ban_sources=""
|
||||||
|
ban_iface=""
|
||||||
|
ban_debug=0
|
||||||
|
ban_backupdir="/mnt"
|
||||||
|
ban_maxqueue=4
|
||||||
|
ban_autoblacklist=1
|
||||||
|
ban_autowhitelist=1
|
||||||
|
ban_realtime="false"
|
||||||
|
ban_fetchutil=""
|
||||||
|
ban_ipt="$(command -v iptables)"
|
||||||
|
ban_ipt_save="$(command -v iptables-save)"
|
||||||
|
ban_ipt_restore="$(command -v iptables-restore)"
|
||||||
|
ban_ipt6="$(command -v ip6tables)"
|
||||||
|
ban_ipt6_save="$(command -v ip6tables-save)"
|
||||||
|
ban_ipt6_restore="$(command -v ip6tables-restore)"
|
||||||
|
ban_ipset="$(command -v ipset)"
|
||||||
|
ban_logger="$(command -v logger)"
|
||||||
|
ban_chain="banIP"
|
||||||
|
ban_action="${1:-"start"}"
|
||||||
|
ban_pidfile="/var/run/banip.pid"
|
||||||
|
ban_rtfile="/tmp/ban_runtime.json"
|
||||||
|
ban_logservice="/etc/banip/banip.service"
|
||||||
|
ban_sshdaemon=""
|
||||||
|
ban_setcnt=0
|
||||||
|
ban_cnt=0
|
||||||
|
|
||||||
|
# load environment
|
||||||
|
#
|
||||||
|
f_envload()
|
||||||
|
{
|
||||||
|
# get system information
|
||||||
|
#
|
||||||
|
ban_sysver="$(ubus -S call system board 2>/dev/null | jsonfilter -e '@.model' -e '@.release.description' | \
|
||||||
|
awk 'BEGIN{ORS=", "}{print $0}' | awk '{print substr($0,1,length($0)-2)}')"
|
||||||
|
|
||||||
|
# parse 'global' and 'extra' section by callback
|
||||||
|
#
|
||||||
|
config_cb()
|
||||||
|
{
|
||||||
|
local type="${1}"
|
||||||
|
if [ "${type}" = "banip" ]
|
||||||
|
then
|
||||||
|
option_cb()
|
||||||
|
{
|
||||||
|
local option="${1}"
|
||||||
|
local value="${2}"
|
||||||
|
eval "${option}=\"${value}\""
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reset_cb
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse 'source' typed sections
|
||||||
|
#
|
||||||
|
parse_config()
|
||||||
|
{
|
||||||
|
local value opt section="${1}" options="ban_src ban_src_6 ban_src_rset ban_src_rset_6 ban_src_settype ban_src_ruletype ban_src_on ban_src_on_6 ban_src_cat"
|
||||||
|
for opt in ${options}
|
||||||
|
do
|
||||||
|
config_get value "${section}" "${opt}"
|
||||||
|
if [ -n "${value}" ]
|
||||||
|
then
|
||||||
|
eval "${opt}_${section}=\"${value}\""
|
||||||
|
if [ "${opt}" = "ban_src" ]
|
||||||
|
then
|
||||||
|
eval "ban_sources=\"${ban_sources} ${section}\""
|
||||||
|
elif [ "${opt}" = "ban_src_6" ]
|
||||||
|
then
|
||||||
|
eval "ban_sources=\"${ban_sources} ${section}_6\""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# load config
|
||||||
|
#
|
||||||
|
config_load banip
|
||||||
|
config_foreach parse_config source
|
||||||
|
|
||||||
|
# log daemon check
|
||||||
|
#
|
||||||
|
if [ "$(/etc/init.d/log running; printf "%u" "${?}")" -eq 1 ]
|
||||||
|
then
|
||||||
|
unset ban_logger
|
||||||
|
f_log "info" "your log daemon 'logd' is not running, please enable 'logd' to use this service"
|
||||||
|
f_rmtemp
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# version check
|
||||||
|
#
|
||||||
|
if [ -z "${ban_basever}" ] || [ "${ban_ver%.*}" != "${ban_basever}" ]
|
||||||
|
then
|
||||||
|
f_log "info" "your banIP config seems to be too old, please update your config with the '--force-maintainer' opkg option"
|
||||||
|
f_rmtemp
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create temp directory & files
|
||||||
|
#
|
||||||
|
f_temp
|
||||||
|
|
||||||
|
# check status
|
||||||
|
#
|
||||||
|
if [ "${ban_enabled}" -eq 0 ]
|
||||||
|
then
|
||||||
|
f_bgserv "stop"
|
||||||
|
f_jsnup disabled
|
||||||
|
f_ipset destroy
|
||||||
|
f_rmbackup
|
||||||
|
f_rmtemp
|
||||||
|
f_log "info" "banIP is currently disabled, please set ban_enabled to '1' to use this service"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# check environment
|
||||||
|
#
|
||||||
|
f_envcheck()
|
||||||
|
{
|
||||||
|
local util utils packages iface tmp cnt=0 cnt_max=0
|
||||||
|
|
||||||
|
f_jsnup "running"
|
||||||
|
f_log "info" "start banIP processing (${ban_action})"
|
||||||
|
|
||||||
|
# check backup directory
|
||||||
|
#
|
||||||
|
if [ ! -d "${ban_backupdir}" ]
|
||||||
|
then
|
||||||
|
f_log "err" "the backup directory '${ban_backupdir}' does not exist or has not been mounted yet, please create the directory or raise the 'ban_triggerdelay' to defer the banIP start"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get wan devices and wan subnets
|
||||||
|
#
|
||||||
|
if [ "${ban_automatic}" = "1" ]
|
||||||
|
then
|
||||||
|
while [ "${cnt}" -le 30 ]
|
||||||
|
do
|
||||||
|
network_find_wan iface
|
||||||
|
if [ -n "${iface}" ] && [ -z "$(printf "%s\\n" "${ban_iface}" | grep -F "${iface}")" ]
|
||||||
|
then
|
||||||
|
ban_iface="${ban_iface} ${iface}"
|
||||||
|
if [ "${cnt_max}" -eq 0 ]
|
||||||
|
then
|
||||||
|
cnt_max=$((cnt+5))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
network_find_wan6 iface
|
||||||
|
if [ -n "${iface}" ] && [ -z "$(printf "%s\\n" "${ban_iface}" | grep -F "${iface}")" ]
|
||||||
|
then
|
||||||
|
ban_iface="${ban_iface} ${iface}"
|
||||||
|
if [ "${cnt_max}" -eq 0 ]
|
||||||
|
then
|
||||||
|
cnt_max=$((cnt+5))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -z "${ban_iface}" ] || [ "${cnt}" -le "${cnt_max}" ]
|
||||||
|
then
|
||||||
|
network_flush_cache
|
||||||
|
cnt=$((cnt+1))
|
||||||
|
sleep 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
for iface in ${ban_iface}
|
||||||
|
do
|
||||||
|
network_get_device tmp "${iface}"
|
||||||
|
if [ -n "${tmp}" ] && [ -z "$(printf "%s\\n" "${ban_dev}" | grep -F "${tmp}")" ]
|
||||||
|
then
|
||||||
|
ban_dev="${ban_dev} ${tmp}"
|
||||||
|
else
|
||||||
|
network_get_physdev tmp "${iface}"
|
||||||
|
if [ -n "${tmp}" ] && [ -z "$(printf "%s\\n" "${ban_dev}" | grep -F "${tmp}")" ]
|
||||||
|
then
|
||||||
|
ban_dev="${ban_dev} ${tmp}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
network_get_subnets tmp "${iface}"
|
||||||
|
if [ -n "${tmp}" ] && [ -z "$(printf "%s\\n" "${ban_subnets}" | grep -F "${tmp}")" ]
|
||||||
|
then
|
||||||
|
ban_subnets="${ban_subnets} ${tmp}"
|
||||||
|
fi
|
||||||
|
network_get_subnets6 tmp "${iface}"
|
||||||
|
if [ -n "${tmp}" ] && [ -z "$(printf "%s\\n" "${ban_subnets6}" | grep -F "${tmp}")" ]
|
||||||
|
then
|
||||||
|
ban_subnets6="${ban_subnets6} ${tmp}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
ban_dev_all="$(ip link show 2>/dev/null | awk 'BEGIN{FS="[@: ]"}/^[0-9:]/{if($3!="lo"){print $3}}')"
|
||||||
|
|
||||||
|
if [ -z "${ban_iface}" ] || [ -z "${ban_dev}" ] || [ -z "${ban_dev_all}" ]
|
||||||
|
then
|
||||||
|
f_log "err" "wan interface(s)/device(s) (${ban_iface:-"-"}/${ban_dev:-"-"}) not found, please please check your configuration"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check fetch utility
|
||||||
|
#
|
||||||
|
if [ -z "${ban_fetchutil}" ]
|
||||||
|
then
|
||||||
|
cnt_max=$((cnt+5))
|
||||||
|
while [ -z "${packages}" ]
|
||||||
|
do
|
||||||
|
packages="$(opkg list-installed 2>/dev/null)"
|
||||||
|
if [ "${cnt}" -gt "${cnt_max}" ]
|
||||||
|
then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
cnt=$((cnt+1))
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
if [ -n "${packages}" ]
|
||||||
|
then
|
||||||
|
utils="aria2c curl wget uclient-fetch"
|
||||||
|
for util in ${utils}
|
||||||
|
do
|
||||||
|
if { [ "${util}" = "uclient-fetch" ] && [ -n "$(printf "%s\\n" "${packages}" | grep "^libustream-")" ]; } || \
|
||||||
|
{ [ "${util}" = "wget" ] && [ -n "$(printf "%s\\n" "${packages}" | grep "^wget -")" ]; } || \
|
||||||
|
{ [ "${util}" != "uclient-fetch" ] && [ "${util}" != "wget" ]; }
|
||||||
|
then
|
||||||
|
ban_fetchutil="$(command -v "${util}")"
|
||||||
|
if [ -x "${ban_fetchutil}" ]
|
||||||
|
then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
unset ban_fetchutil util
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
util="${ban_fetchutil}"
|
||||||
|
ban_fetchutil="$(command -v "${util}")"
|
||||||
|
if [ ! -x "${ban_fetchutil}" ]
|
||||||
|
then
|
||||||
|
unset ban_fetchutil util
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
case "${util}" in
|
||||||
|
"aria2c")
|
||||||
|
ban_fetchparm="${ban_fetchparm:-"--timeout=20 --allow-overwrite=true --auto-file-renaming=false --check-certificate=true --dir=" " -o"}"
|
||||||
|
;;
|
||||||
|
"curl")
|
||||||
|
ban_fetchparm="${ban_fetchparm:-"--connect-timeout 20 -o"}"
|
||||||
|
;;
|
||||||
|
"uclient-fetch")
|
||||||
|
ban_fetchparm="${ban_fetchparm:-"--timeout=20 -O"}"
|
||||||
|
;;
|
||||||
|
"wget")
|
||||||
|
ban_fetchparm="${ban_fetchparm:-"--no-cache --no-cookies --max-redirect=0 --timeout=20 -O"}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if [ -z "${ban_fetchutil}" ] || [ -z "${ban_fetchparm}" ]
|
||||||
|
then
|
||||||
|
f_log "err" "download utility with SSL support not found, please install 'uclient-fetch' with a 'libustream-*' variant or another download utility like 'wget', 'curl' or 'aria2'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check ssh daemon
|
||||||
|
#
|
||||||
|
if [ -z "${ban_sshdaemon}" ]
|
||||||
|
then
|
||||||
|
utils="dropbear sshd"
|
||||||
|
for util in ${utils}
|
||||||
|
do
|
||||||
|
if [ -x "$(command -v "${util}")" ]
|
||||||
|
then
|
||||||
|
ban_sshdaemon="${util}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [ -z "${ban_sshdaemon}" ]
|
||||||
|
then
|
||||||
|
f_log "err" "ssh daemon not found, please install 'dropbear' or 'sshd'"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# create temporary files and directories
|
||||||
|
#
|
||||||
|
f_temp()
|
||||||
|
{
|
||||||
|
if [ -d "/tmp" ] && [ -z "${ban_tmpdir}" ]
|
||||||
|
then
|
||||||
|
ban_tmpdir="$(mktemp -p /tmp -d)"
|
||||||
|
ban_tmpfile="$(mktemp -p "${ban_tmpdir}" -tu)"
|
||||||
|
elif [ ! -d "/tmp" ]
|
||||||
|
then
|
||||||
|
f_log "err" "the temp directory '/tmp' does not exist or has not been mounted yet, please create the directory or raise the 'ban_triggerdelay' to defer the banIP start"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${ban_pidfile}" ] || [ ! -s "${ban_pidfile}" ]
|
||||||
|
then
|
||||||
|
printf "%s" "${$}" > "${ban_pidfile}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove temporary files and directories
|
||||||
|
#
|
||||||
|
f_rmtemp()
|
||||||
|
{
|
||||||
|
if [ -d "${ban_tmpdir}" ]
|
||||||
|
then
|
||||||
|
rm -rf "${ban_tmpdir}"
|
||||||
|
fi
|
||||||
|
> "${ban_pidfile}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove backup files
|
||||||
|
#
|
||||||
|
f_rmbackup()
|
||||||
|
{
|
||||||
|
if [ -d "${ban_backupdir}" ]
|
||||||
|
then
|
||||||
|
rm -f "${ban_backupdir}"/banIP.*.gz
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# iptables rules engine
|
||||||
|
#
|
||||||
|
f_iptrule()
|
||||||
|
{
|
||||||
|
local rc timeout="-w 5" action="${1}" rule="${2}"
|
||||||
|
|
||||||
|
if [ "${src_name##*_}" = "6" ]
|
||||||
|
then
|
||||||
|
if [ -x "${ban_ipt6}" ]
|
||||||
|
then
|
||||||
|
rc="$("${ban_ipt6}" "${timeout}" -C ${rule} 2>/dev/null; printf "%u" ${?})"
|
||||||
|
|
||||||
|
if { [ "${rc}" -ne 0 ] && { [ "${action}" = "-A" ] || [ "${action}" = "-I" ]; } } || \
|
||||||
|
{ [ "${rc}" -eq 0 ] && [ "${action}" = "-D" ]; }
|
||||||
|
then
|
||||||
|
"${ban_ipt6}" "${timeout}" "${action}" ${rule} 2>/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -x "${ban_ipt}" ]
|
||||||
|
then
|
||||||
|
rc="$("${ban_ipt}" "${timeout}" -C ${rule} 2>/dev/null; printf "%u" ${?})"
|
||||||
|
|
||||||
|
if { [ "${rc}" -ne 0 ] && { [ "${action}" = "-A" ] || [ "${action}" = "-I" ]; } } || \
|
||||||
|
{ [ "${rc}" -eq 0 ] && [ "${action}" = "-D" ]; }
|
||||||
|
then
|
||||||
|
"${ban_ipt}" "${timeout}" "${action}" ${rule} 2>/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "${?}" -ne 0 ]
|
||||||
|
then
|
||||||
|
> "${tmp_err}"
|
||||||
|
f_log "info" "can't create iptables rule: action: '${action:-"-"}', rule: '${rule:-"-"}'"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove/add iptables rules
|
||||||
|
#
|
||||||
|
f_iptadd()
|
||||||
|
{
|
||||||
|
local rm="${1}" dev
|
||||||
|
|
||||||
|
for dev in ${ban_dev_all}
|
||||||
|
do
|
||||||
|
f_iptrule "-D" "${ban_chain} -i ${dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}"
|
||||||
|
f_iptrule "-D" "${ban_chain} -o ${dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${rm}" ] && [ "${cnt}" -gt 0 ]
|
||||||
|
then
|
||||||
|
if [ "${src_ruletype}" != "dst" ]
|
||||||
|
then
|
||||||
|
if [ "${src_name##*_}" = "6" ]
|
||||||
|
then
|
||||||
|
# dummy, special IPv6 rules
|
||||||
|
/bin/true
|
||||||
|
else
|
||||||
|
f_iptrule "-I" "${wan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN"
|
||||||
|
fi
|
||||||
|
f_iptrule "-A" "${wan_input} -j ${ban_chain}"
|
||||||
|
f_iptrule "-A" "${wan_forward} -j ${ban_chain}"
|
||||||
|
for dev in ${ban_dev}
|
||||||
|
do
|
||||||
|
f_iptrule "${action:-"-A"}" "${ban_chain} -i ${dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} src -j ${target_src}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [ "${src_ruletype}" != "src" ]
|
||||||
|
then
|
||||||
|
if [ "${src_name##*_}" = "6" ]
|
||||||
|
then
|
||||||
|
# dummy, special IPv6 rules
|
||||||
|
/bin/true
|
||||||
|
else
|
||||||
|
f_iptrule "-I" "${lan_input} -p udp --dport 67:68 --sport 67:68 -j RETURN"
|
||||||
|
fi
|
||||||
|
f_iptrule "-A" "${lan_input} -j ${ban_chain}"
|
||||||
|
f_iptrule "-A" "${lan_forward} -j ${ban_chain}"
|
||||||
|
for dev in ${ban_dev}
|
||||||
|
do
|
||||||
|
f_iptrule "${action:-"-A"}" "${ban_chain} -o ${dev} -m conntrack --ctstate NEW -m set --match-set ${src_name} dst -j ${target_dst}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -x "${ban_ipset}" ] && [ -n "$("${ban_ipset}" -q -n list "${src_name}")" ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q destroy "${src_name}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ipset/iptables actions
|
||||||
|
#
|
||||||
|
f_ipset()
|
||||||
|
{
|
||||||
|
local out_rc source action ruleset ruleset_6 rule cnt=0 cnt_ip=0 cnt_cidr=0 timeout="-w 5" mode="${1}" in_rc="${src_rc:-0}"
|
||||||
|
|
||||||
|
if [ "${src_name%_6*}" = "whitelist" ]
|
||||||
|
then
|
||||||
|
target_src="RETURN"
|
||||||
|
target_dst="RETURN"
|
||||||
|
action="-I"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${mode}" in
|
||||||
|
"backup")
|
||||||
|
gzip -cf "${tmp_load}" 2>/dev/null > "${ban_backupdir}/banIP.${src_name}.gz"
|
||||||
|
out_rc="${?:-"${in_rc}"}"
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}"
|
||||||
|
return "${out_rc}"
|
||||||
|
;;
|
||||||
|
"restore")
|
||||||
|
if [ -f "${ban_backupdir}/banIP.${src_name}.gz" ]
|
||||||
|
then
|
||||||
|
zcat "${ban_backupdir}/banIP.${src_name}.gz" 2>/dev/null > "${tmp_load}"
|
||||||
|
out_rc="${?}"
|
||||||
|
fi
|
||||||
|
out_rc="${out_rc:-"${in_rc}"}"
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}"
|
||||||
|
return "${out_rc}"
|
||||||
|
;;
|
||||||
|
"remove")
|
||||||
|
if [ -f "${ban_backupdir}/banIP.${src_name}.gz" ]
|
||||||
|
then
|
||||||
|
rm -f "${ban_backupdir}/banIP.${src_name}.gz"
|
||||||
|
out_rc="${?}"
|
||||||
|
fi
|
||||||
|
out_rc="${out_rc:-"${in_rc}"}"
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, out_rc: ${out_rc}"
|
||||||
|
return "${out_rc}"
|
||||||
|
;;
|
||||||
|
"initial")
|
||||||
|
if [ -x "${ban_ipt}" ] && [ -z "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
|
||||||
|
then
|
||||||
|
"${ban_ipt}" "${timeout}" -N "${ban_chain}" 2>/dev/null
|
||||||
|
out_rc="${?}"
|
||||||
|
elif [ -x "${ban_ipt}" ]
|
||||||
|
then
|
||||||
|
src_name="ruleset"
|
||||||
|
ruleset="${ban_wan_input_chain:-"input_wan_rule"} ${ban_wan_forward_chain:-"forwarding_wan_rule"} ${ban_lan_input_chain:-"input_lan_rule"} ${ban_lan_forward_chain:-"forwarding_lan_rule"}"
|
||||||
|
for rule in ${ruleset}
|
||||||
|
do
|
||||||
|
f_iptrule "-D" "${rule} -j ${ban_chain}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [ -x "${ban_ipt6}" ] && [ -z "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
|
||||||
|
then
|
||||||
|
"${ban_ipt6}" "${timeout}" -N "${ban_chain}" 2>/dev/null
|
||||||
|
out_rc="${?}"
|
||||||
|
elif [ -x "${ban_ipt6}" ]
|
||||||
|
then
|
||||||
|
src_name="ruleset_6"
|
||||||
|
ruleset_6="${ban_wan_input_chain_6:-"input_wan_rule"} ${ban_wan_forward_chain_6:-"forwarding_wan_rule"} ${ban_lan_input_chain_6:-"input_lan_rule"} ${ban_lan_forward_chain_6:-"forwarding_lan_rule"}"
|
||||||
|
for rule in ${ruleset_6}
|
||||||
|
do
|
||||||
|
f_iptrule "-D" "${rule} -j ${ban_chain}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
out_rc="${out_rc:-"${in_rc}"}"
|
||||||
|
f_log "debug" "f_ipset ::: name: -, mode: ${mode:-"-"}, chain: ${ban_chain:-"-"}, ruleset: ${ruleset:-"-"}, ruleset_6: ${ruleset_6:-"-"}, out_rc: ${out_rc}"
|
||||||
|
return "${out_rc}"
|
||||||
|
;;
|
||||||
|
"create")
|
||||||
|
if [ -x "${ban_ipset}" ]
|
||||||
|
then
|
||||||
|
if [ -s "${tmp_file}" ] && [ -z "$("${ban_ipset}" -q -n list "${src_name}")" ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q create "${src_name}" hash:"${src_settype}" hashsize 64 maxelem 262144 family "${src_setipv}" counters
|
||||||
|
out_rc="${?}"
|
||||||
|
else
|
||||||
|
"${ban_ipset}" -q flush "${src_name}"
|
||||||
|
out_rc="${?}"
|
||||||
|
fi
|
||||||
|
if [ -s "${tmp_file}" ] && [ "${out_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q -! restore < "${tmp_file}"
|
||||||
|
out_rc="${?}"
|
||||||
|
if [ "${out_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q save "${src_name}" > "${tmp_file}"
|
||||||
|
cnt="$(($(wc -l 2>/dev/null < "${tmp_file}")-1))"
|
||||||
|
cnt_cidr="$(grep -cF "/" "${tmp_file}")"
|
||||||
|
cnt_ip="$((cnt-cnt_cidr))"
|
||||||
|
printf "%s\\n" "${cnt}" > "${tmp_cnt}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
f_iptadd
|
||||||
|
fi
|
||||||
|
end_ts="$(date +%s)"
|
||||||
|
out_rc="${out_rc:-"${in_rc}"}"
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, settype: ${src_settype:-"-"}, setipv: ${src_setipv:-"-"}, ruletype: ${src_ruletype:-"-"}, count(sum/ip/cidr): ${cnt}/${cnt_ip}/${cnt_cidr}, time: $((end_ts-start_ts)), out_rc: ${out_rc}"
|
||||||
|
return "${out_rc}"
|
||||||
|
;;
|
||||||
|
"refresh")
|
||||||
|
if [ -x "${ban_ipset}" ] && [ -n "$("${ban_ipset}" -q -n list "${src_name}")" ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q save "${src_name}" > "${tmp_file}"
|
||||||
|
out_rc="${?}"
|
||||||
|
if [ -s "${tmp_file}" ] && [ "${out_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
cnt="$(($(wc -l 2>/dev/null < "${tmp_file}")-1))"
|
||||||
|
cnt_cidr="$(grep -cF "/" "${tmp_file}")"
|
||||||
|
cnt_ip="$((cnt-cnt_cidr))"
|
||||||
|
printf "%s\\n" "${cnt}" > "${tmp_cnt}"
|
||||||
|
fi
|
||||||
|
f_iptadd
|
||||||
|
fi
|
||||||
|
end_ts="$(date +%s)"
|
||||||
|
out_rc="${out_rc:-"${in_rc}"}"
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}, count: ${cnt}/${cnt_ip}/${cnt_cidr}, time: $((end_ts-start_ts)), out_rc: ${out_rc}"
|
||||||
|
return "${out_rc}"
|
||||||
|
;;
|
||||||
|
"flush")
|
||||||
|
f_iptadd "remove"
|
||||||
|
|
||||||
|
if [ -x "${ban_ipset}" ] && [ -n "$("${ban_ipset}" -q -n list "${src_name}")" ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q flush "${src_name}"
|
||||||
|
"${ban_ipset}" -q destroy "${src_name}"
|
||||||
|
fi
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}"
|
||||||
|
;;
|
||||||
|
"destroy")
|
||||||
|
if [ -x "${ban_ipt}" ] && [ -x "${ban_ipt_save}" ] && [ -x "${ban_ipt_restore}" ] && \
|
||||||
|
[ -n "$("${ban_ipt}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
|
||||||
|
then
|
||||||
|
"${ban_ipt_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt_restore}"
|
||||||
|
"${ban_ipt}" "${timeout}" -F "${ban_chain}" 2>/dev/null
|
||||||
|
"${ban_ipt}" "${timeout}" -X "${ban_chain}" 2>/dev/null
|
||||||
|
fi
|
||||||
|
if [ -x "${ban_ipt6}" ] && [ -x "${ban_ipt6_save}" ] && [ -x "${ban_ipt6_restore}" ] && \
|
||||||
|
[ -n "$("${ban_ipt6}" "${timeout}" -nL "${ban_chain}" 2>/dev/null)" ]
|
||||||
|
then
|
||||||
|
"${ban_ipt6_save}" | grep -v -- "-j ${ban_chain}" | "${ban_ipt6_restore}"
|
||||||
|
"${ban_ipt6}" "${timeout}" -F "${ban_chain}" 2>/dev/null
|
||||||
|
"${ban_ipt6}" "${timeout}" -X "${ban_chain}" 2>/dev/null
|
||||||
|
fi
|
||||||
|
for source in ${ban_sources}
|
||||||
|
do
|
||||||
|
if [ -x "${ban_ipset}" ] && [ -n "$("${ban_ipset}" -q -n list "${source}")" ]
|
||||||
|
then
|
||||||
|
"${ban_ipset}" -q destroy "${source}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
f_log "debug" "f_ipset ::: name: ${src_name:-"-"}, mode: ${mode:-"-"}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# write to syslog
|
||||||
|
#
|
||||||
|
f_log()
|
||||||
|
{
|
||||||
|
local class="${1}" log_msg="${2}"
|
||||||
|
|
||||||
|
if [ -n "${log_msg}" ] && { [ "${class}" != "debug" ] || [ "${ban_debug}" -eq 1 ]; }
|
||||||
|
then
|
||||||
|
if [ -x "${ban_logger}" ]
|
||||||
|
then
|
||||||
|
"${ban_logger}" -p "${class}" -t "banIP-${ban_ver}[${$}]" "${log_msg}"
|
||||||
|
else
|
||||||
|
printf "%s %s %s\\n" "${class}" "banIP-${ban_ver}[${$}]" "${log_msg}"
|
||||||
|
fi
|
||||||
|
if [ "${class}" = "err" ]
|
||||||
|
then
|
||||||
|
f_jsnup error
|
||||||
|
f_ipset destroy
|
||||||
|
f_rmbackup
|
||||||
|
f_rmtemp
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# start log service to trace failed ssh/luci logins
|
||||||
|
#
|
||||||
|
f_bgserv()
|
||||||
|
{
|
||||||
|
local bg_pid status="${1}"
|
||||||
|
|
||||||
|
bg_pid="$(pgrep -f "^/bin/sh ${ban_logservice}.*|^logread -f -e ${ban_sshdaemon}\|luci: failed login|^grep -qE Exit before auth|luci: failed login|[0-9]+ \[preauth\]$" | awk '{ORS=" "; print $1}')"
|
||||||
|
if [ -z "${bg_pid}" ] && [ "${status}" = "start" ] \
|
||||||
|
&& [ -x "${ban_logservice}" ] && [ "${ban_realtime}" = "true" ]
|
||||||
|
then
|
||||||
|
( "${ban_logservice}" "${ban_ver}" "${ban_sshdaemon}" & )
|
||||||
|
elif [ -n "${bg_pid}" ] && [ "${status}" = "stop" ]
|
||||||
|
then
|
||||||
|
kill -HUP "${bg_pid}" 2>/dev/null
|
||||||
|
fi
|
||||||
|
f_log "debug" "f_bgserv ::: status: ${status:-"-"}, bg_pid: ${bg_pid:-"-"}, ban_realtime: ${ban_realtime:-"-"}, log_service: ${ban_logservice:-"-"}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# main function for banIP processing
|
||||||
|
#
|
||||||
|
f_main()
|
||||||
|
{
|
||||||
|
local pid pid_list start_ts end_ts ip tmp_raw tmp_cnt tmp_load tmp_file mem_total mem_free cnt=1
|
||||||
|
local src_name src_on src_url src_rset src_setipv src_settype src_ruletype src_cat src_log src_addon src_ts src_rc
|
||||||
|
local wan_input wan_forward lan_input lan_forward target_src target_dst ssh_log luci_log
|
||||||
|
|
||||||
|
ssh_log="$(logread -e "${ban_sshdaemon}" | grep -o "${ban_sshdaemon}.*" | sed 's/:[0-9]*$//g')"
|
||||||
|
luci_log="$(logread -e "luci: failed login" | grep -o "luci:.*")"
|
||||||
|
mem_total="$(awk '/^MemTotal/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
|
||||||
|
mem_free="$(awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo" 2>/dev/null)"
|
||||||
|
f_log "debug" "f_main ::: fetch_util: ${ban_fetchutil:-"-"}, fetch_parm: ${ban_fetchparm:-"-"}, ssh_daemon: ${ban_sshdaemon}, interface(s): ${ban_iface:-"-"}, device(s): ${ban_dev:-"-"}, all_devices: ${ban_dev_all:-"-"}, backup_dir: ${ban_backupdir:-"-"}, mem_total: ${mem_total:-0}, mem_free: ${mem_free:-0}, max_queue: ${ban_maxqueue}"
|
||||||
|
|
||||||
|
# chain creation
|
||||||
|
#
|
||||||
|
f_ipset initial
|
||||||
|
if [ "${?}" -ne 0 ]
|
||||||
|
then
|
||||||
|
f_log "err" "banIP processing failed, fatal error during iptables chain creation (${ban_sysver})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# main loop
|
||||||
|
#
|
||||||
|
for src_name in ${ban_sources}
|
||||||
|
do
|
||||||
|
unset src_on
|
||||||
|
if [ "${src_name##*_}" = "6" ]
|
||||||
|
then
|
||||||
|
if [ -x "${ban_ipt6}" ]
|
||||||
|
then
|
||||||
|
src_on="$(eval printf "%s" \"\$\{ban_src_on_6_${src_name%_6*}\}\")"
|
||||||
|
src_url="$(eval printf "%s" \"\$\{ban_src_6_${src_name%_6*}\}\")"
|
||||||
|
src_rset="$(eval printf "%s" \"\$\{ban_src_rset_6_${src_name%_6*}\}\")"
|
||||||
|
src_setipv="inet6"
|
||||||
|
wan_input="${ban_wan_input_chain_6:-"input_wan_rule"}"
|
||||||
|
wan_forward="${ban_wan_forward_chain_6:-"forwarding_wan_rule"}"
|
||||||
|
lan_input="${ban_lan_input_chain_6:-"input_lan_rule"}"
|
||||||
|
lan_forward="${ban_lan_forward_chain_6:-"forwarding_lan_rule"}"
|
||||||
|
target_src="${ban_target_src_6:-"DROP"}"
|
||||||
|
target_dst="${ban_target_dst_6:-"REJECT"}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -x "${ban_ipt}" ]
|
||||||
|
then
|
||||||
|
src_on="$(eval printf "%s" \"\$\{ban_src_on_${src_name}\}\")"
|
||||||
|
src_url="$(eval printf "%s" \"\$\{ban_src_${src_name}\}\")"
|
||||||
|
src_rset="$(eval printf "%s" \"\$\{ban_src_rset_${src_name}\}\")"
|
||||||
|
src_setipv="inet"
|
||||||
|
wan_input="${ban_wan_input_chain:-"input_wan_rule"}"
|
||||||
|
wan_forward="${ban_wan_forward_chain:-"forwarding_wan_rule"}"
|
||||||
|
lan_input="${ban_lan_input_chain:-"input_lan_rule"}"
|
||||||
|
lan_forward="${ban_lan_forward_chain:-"forwarding_lan_rule"}"
|
||||||
|
target_src="${ban_target_src:-"DROP"}"
|
||||||
|
target_dst="${ban_target_dst:-"REJECT"}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
src_settype="$(eval printf "%s" \"\$\{ban_src_settype_${src_name%_6*}\}\")"
|
||||||
|
src_ruletype="$(eval printf "%s" \"\$\{ban_src_ruletype_${src_name%_6*}\}\")"
|
||||||
|
src_cat="$(eval printf "%s" \"\$\{ban_src_cat_${src_name%_6*}\}\")"
|
||||||
|
src_addon=""
|
||||||
|
src_rc=4
|
||||||
|
tmp_load="${ban_tmpfile}.${src_name}.load"
|
||||||
|
tmp_file="${ban_tmpfile}.${src_name}.file"
|
||||||
|
tmp_raw="${tmp_file}.raw"
|
||||||
|
tmp_cnt="${tmp_file}.cnt"
|
||||||
|
tmp_err="${tmp_file}.err"
|
||||||
|
|
||||||
|
# basic pre-checks
|
||||||
|
#
|
||||||
|
f_log "debug" "f_main ::: name: ${src_name}, src_on: ${src_on:-"-"}"
|
||||||
|
|
||||||
|
if [ -z "${src_on}" ] || [ "${src_on}" != "1" ] || [ -z "${src_url}" ] || \
|
||||||
|
[ -z "${src_rset}" ] || [ -z "${src_settype}" ] || [ -z "${src_ruletype}" ]
|
||||||
|
then
|
||||||
|
f_ipset flush
|
||||||
|
f_ipset remove
|
||||||
|
continue
|
||||||
|
elif [ "${ban_action}" = "refresh" ] && [ ! -f "${src_url}" ]
|
||||||
|
then
|
||||||
|
start_ts="$(date +%s)"
|
||||||
|
f_ipset refresh
|
||||||
|
if [ "${?}" -eq 0 ]
|
||||||
|
then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# download queue processing
|
||||||
|
#
|
||||||
|
(
|
||||||
|
start_ts="$(date +%s)"
|
||||||
|
if [ "${ban_action}" = "start" ] && [ ! -f "${src_url}" ]
|
||||||
|
then
|
||||||
|
f_ipset restore
|
||||||
|
fi
|
||||||
|
src_rc="${?}"
|
||||||
|
if [ "${src_rc}" -ne 0 ] || [ ! -s "${tmp_load}" ]
|
||||||
|
then
|
||||||
|
if [ -f "${src_url}" ]
|
||||||
|
then
|
||||||
|
src_log="$(cat "${src_url}" 2>/dev/null > "${tmp_load}")"
|
||||||
|
src_rc="${?}"
|
||||||
|
case "${src_name}" in
|
||||||
|
"whitelist")
|
||||||
|
src_addon="${ban_subnets}"
|
||||||
|
;;
|
||||||
|
"whitelist_6")
|
||||||
|
src_addon="${ban_subnets6}"
|
||||||
|
;;
|
||||||
|
"blacklist")
|
||||||
|
if [ "${ban_sshdaemon}" = "dropbear" ]
|
||||||
|
then
|
||||||
|
pid_list="$(printf "%s\\n" "${ssh_log}" | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
|
||||||
|
for pid in ${pid_list}
|
||||||
|
do
|
||||||
|
src_addon="${src_addon} $(printf "%s\\n" "${ssh_log}" | grep -F "${pid}" | awk 'match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}$/){ORS=" ";print substr($0,RSTART,RLENGTH);exit}')"
|
||||||
|
done
|
||||||
|
elif [ "${ban_sshdaemon}" = "sshd" ]
|
||||||
|
then
|
||||||
|
src_addon="$(printf "%s\\n" "${ssh_log}" | grep -E "[0-9]+ \[preauth\]$" | awk 'match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}$/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
|
||||||
|
fi
|
||||||
|
src_addon="${src_addon} $(printf "%s\\n" "${luci_log}" | awk 'match($0,/([0-9]{1,3}\.){3}[0-9]{1,3}$/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
|
||||||
|
;;
|
||||||
|
"blacklist_6")
|
||||||
|
if [ "${ban_sshdaemon}" = "dropbear" ]
|
||||||
|
then
|
||||||
|
pid_list="$(printf "%s\\n" "${ssh_log}" | grep -F "Exit before auth" | awk 'match($0,/(\[[0-9]+\])/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
|
||||||
|
for pid in ${pid_list}
|
||||||
|
do
|
||||||
|
src_addon="${src_addon} $(printf "%s\\n" "${ssh_log}" | grep -F "${pid}" | awk 'match($0,/(([0-9A-f]{0,4}::?){1,7}[0-9A-f]{0,4}$)/){ORS=" ";print substr($0,RSTART,RLENGTH);exit}')"
|
||||||
|
done
|
||||||
|
elif [ "${ban_sshdaemon}" = "sshd" ]
|
||||||
|
then
|
||||||
|
src_addon="$(printf "%s\\n" "${ssh_log}" | grep -E "[0-9]+ \[preauth\]$" | awk 'match($0,/(([0-9A-f]{0,4}::?){1,7}[0-9A-f]{0,4}$)/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
|
||||||
|
fi
|
||||||
|
src_addon="${src_addon} $(printf "%s\\n" "${luci_log}" | awk 'match($0,/(([0-9A-f]{0,4}::?){1,7}[0-9A-f]{0,4}$)/){ORS=" ";print substr($0,RSTART,RLENGTH)}')"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
for ip in ${src_addon}
|
||||||
|
do
|
||||||
|
if [ -z "$(grep -F "${ip}" "${src_url}")" ]
|
||||||
|
then
|
||||||
|
printf "%s\\n" "${ip}" >> "${tmp_load}"
|
||||||
|
if { [ "${src_name//_*/}" = "blacklist" ] && [ "${ban_autoblacklist}" -eq 1 ]; } || \
|
||||||
|
{ [ "${src_name//_*/}" = "whitelist" ] && [ "${ban_autowhitelist}" -eq 1 ]; }
|
||||||
|
then
|
||||||
|
src_ts="# auto-added $(date "+%d.%m.%Y %H:%M:%S")"
|
||||||
|
printf "%s %s\\n" "${ip}" "${src_ts}" >> "${src_url}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
elif [ -n "${src_cat}" ]
|
||||||
|
then
|
||||||
|
if [ "${src_cat//[0-9]/}" != "${src_cat}" ]
|
||||||
|
then
|
||||||
|
for as in ${src_cat}
|
||||||
|
do
|
||||||
|
src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}AS${as}" 2>&1)"
|
||||||
|
src_rc="${?}"
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
jsonfilter -i "${tmp_raw}" -e '@.data.prefixes.*.prefix' 2>/dev/null >> "${tmp_load}"
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
f_ipset backup
|
||||||
|
elif [ "${ban_action}" != "start" ]
|
||||||
|
then
|
||||||
|
f_ipset restore
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
for co in ${src_cat}
|
||||||
|
do
|
||||||
|
src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}${co}&v4_format=prefix" 2>&1)"
|
||||||
|
src_rc="${?}"
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
if [ "${src_name##*_}" = "6" ]
|
||||||
|
then
|
||||||
|
jsonfilter -i "${tmp_raw}" -e '@.data.resources.ipv6.*' 2>/dev/null >> "${tmp_load}"
|
||||||
|
else
|
||||||
|
jsonfilter -i "${tmp_raw}" -e '@.data.resources.ipv4.*' 2>/dev/null >> "${tmp_load}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
f_ipset backup
|
||||||
|
elif [ "${ban_action}" != "start" ]
|
||||||
|
then
|
||||||
|
f_ipset restore
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
src_log="$("${ban_fetchutil}" ${ban_fetchparm} "${tmp_raw}" "${src_url}" 2>&1)"
|
||||||
|
src_rc="${?}"
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
zcat "${tmp_raw}" 2>/dev/null > "${tmp_load}"
|
||||||
|
src_rc="${?}"
|
||||||
|
if [ "${src_rc}" -ne 0 ]
|
||||||
|
then
|
||||||
|
mv -f "${tmp_raw}" "${tmp_load}"
|
||||||
|
src_rc="${?}"
|
||||||
|
fi
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
f_ipset backup
|
||||||
|
src_rc="${?}"
|
||||||
|
fi
|
||||||
|
elif [ "${ban_action}" != "start" ]
|
||||||
|
then
|
||||||
|
f_ipset restore
|
||||||
|
src_rc="${?}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
awk "${src_rset}" "${tmp_load}" 2>/dev/null > "${tmp_file}"
|
||||||
|
src_rc="${?}"
|
||||||
|
if [ "${src_rc}" -eq 0 ]
|
||||||
|
then
|
||||||
|
f_ipset create
|
||||||
|
src_rc="${?}"
|
||||||
|
elif [ "${ban_action}" != "refresh" ]
|
||||||
|
then
|
||||||
|
f_ipset refresh
|
||||||
|
src_rc="${?}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
src_log="$(printf "%s" "${src_log}" | awk '{ORS=" ";print $0}')"
|
||||||
|
if [ "${ban_action}" != "refresh" ]
|
||||||
|
then
|
||||||
|
f_ipset refresh
|
||||||
|
src_rc="${?}"
|
||||||
|
fi
|
||||||
|
f_log "debug" "f_main ::: name: ${src_name}, url: ${src_url}, rc: ${src_rc}, log: ${src_log:-"-"}"
|
||||||
|
fi
|
||||||
|
)&
|
||||||
|
hold="$((cnt%ban_maxqueue))"
|
||||||
|
if [ "${hold}" -eq 0 ]
|
||||||
|
then
|
||||||
|
wait
|
||||||
|
fi
|
||||||
|
cnt="$((cnt+1))"
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
if [ -z "$(ls "${ban_tmpfile}".*.err 2>/dev/null)" ]
|
||||||
|
then
|
||||||
|
for cnt in $(cat "${ban_tmpfile}".*.cnt 2>/dev/null)
|
||||||
|
do
|
||||||
|
ban_cnt="$((ban_cnt+cnt))"
|
||||||
|
done
|
||||||
|
if [ "${ban_cnt}" -gt 0 ]
|
||||||
|
then
|
||||||
|
ban_setcnt="$(ls "${ban_tmpfile}".*.cnt 2>/dev/null | wc -l)"
|
||||||
|
fi
|
||||||
|
f_log "info" "${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes loaded successfully (${ban_sysver})"
|
||||||
|
f_bgserv "start"
|
||||||
|
f_jsnup
|
||||||
|
f_rmtemp
|
||||||
|
else
|
||||||
|
f_log "err" "banIP processing failed, fatal iptables error(s) during subshell processing (${ban_sysver})"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# update runtime information
|
||||||
|
#
|
||||||
|
f_jsnup()
|
||||||
|
{
|
||||||
|
local rundate status="${1:-"enabled"}"
|
||||||
|
|
||||||
|
rundate="$(date "+%d.%m.%Y %H:%M:%S")"
|
||||||
|
ban_cntinfo="${ban_setcnt} IPSets with overall ${ban_cnt} IPs/Prefixes"
|
||||||
|
|
||||||
|
> "${ban_rtfile}"
|
||||||
|
json_load_file "${ban_rtfile}" >/dev/null 2>&1
|
||||||
|
json_init
|
||||||
|
json_add_object "data"
|
||||||
|
json_add_string "status" "${status}"
|
||||||
|
json_add_string "version" "${ban_ver}"
|
||||||
|
json_add_string "util_info" "${ban_fetchutil:-"-"}, ${ban_realtime:-"-"}"
|
||||||
|
json_add_string "ipset_info" "${ban_cntinfo:-"-"}"
|
||||||
|
json_add_string "backup_dir" "${ban_backupdir}"
|
||||||
|
json_add_string "last_run" "${rundate:-"-"}"
|
||||||
|
json_add_string "system" "${ban_sysver}"
|
||||||
|
json_close_object
|
||||||
|
json_dump > "${ban_rtfile}"
|
||||||
|
f_log "debug" "f_jsnup ::: status: ${status}, setcnt: ${ban_setcnt}, cnt: ${ban_cnt}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# source required system libraries
|
||||||
|
#
|
||||||
|
if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]
|
||||||
|
then
|
||||||
|
. "/lib/functions.sh"
|
||||||
|
. "/lib/functions/network.sh"
|
||||||
|
. "/usr/share/libubox/jshn.sh"
|
||||||
|
else
|
||||||
|
f_log "err" "system libraries not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# handle different banIP actions
|
||||||
|
#
|
||||||
|
f_envload
|
||||||
|
case "${ban_action}" in
|
||||||
|
"stop")
|
||||||
|
f_bgserv "stop"
|
||||||
|
f_jsnup stopped
|
||||||
|
f_ipset destroy
|
||||||
|
f_rmbackup
|
||||||
|
f_rmtemp
|
||||||
|
;;
|
||||||
|
"start"|"restart"|"reload"|"refresh")
|
||||||
|
f_bgserv "stop"
|
||||||
|
f_envcheck
|
||||||
|
f_main
|
||||||
|
;;
|
||||||
|
esac
|
0
net/banip/files/banip.whitelist
Normal file
0
net/banip/files/banip.whitelist
Normal file
69
net/dcwapd/Makefile
Normal file
69
net/dcwapd/Makefile
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2019 EWSI
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=dcwapd
|
||||||
|
PKG_VERSION:=1.1.0
|
||||||
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
|
PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
|
||||||
|
PKG_HASH:=58e52bf4e7526b2f26319740549dbcc6f6ab505f587815ee8731e40f7fecb625
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
|
||||||
|
PKG_LICENSE:=Apache-2.0
|
||||||
|
PKG_LICENSE_FILES:=COPYING
|
||||||
|
|
||||||
|
PKG_FIXUP:=autoreconf
|
||||||
|
PKG_INSTALL:=1
|
||||||
|
PKG_BUILD_PARALLEL:=1
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/uclibc++.mk
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/dcwapd
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
SUBMENU:=Routing and Redirection
|
||||||
|
TITLE:=Dual-Channel WiFi AP daemon
|
||||||
|
URL:=https://www.edgewaterwireless.com
|
||||||
|
DEPENDS:=$(CXX_DEPENDS) +kmod-macremapper +libdcwsocket +libdcwproto +mrmctl +libuci
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/dcwapd/description
|
||||||
|
Implementation of the Dual-Channel WiFi AP daemon
|
||||||
|
endef
|
||||||
|
|
||||||
|
CONFIGURE_ARGS += \
|
||||||
|
--enable-platform=linuxjsonstatic \
|
||||||
|
--enable-shared
|
||||||
|
|
||||||
|
TARGET_CXXFLAGS += -std=c++11 -DRAPIDJSON_HAS_CXX11_RVALUE_REFS=0 -ffunction-sections -fdata-sections -flto
|
||||||
|
TARGET_LDFLAGS += -ldcwproto -ldcwsocket -lmrmfilterparser -luci -Wl,--gc-sections,--as-needed
|
||||||
|
|
||||||
|
define Build/InstallDev
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/dcwapd/install
|
||||||
|
$(INSTALL_DIR) $(1)/bin
|
||||||
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/bin/
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
# Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
|
||||||
|
|
||||||
|
# UCI config file
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_DATA) ./files/dcwapd.uci $(1)/etc/config/dcwapd
|
||||||
|
|
||||||
|
# Init script
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/dcwapd.init $(1)/etc/init.d/dcwapd
|
||||||
|
endef
|
||||||
|
$(eval $(call BuildPackage,dcwapd))
|
326
net/dcwapd/files/dcwapd.init
Normal file
326
net/dcwapd/files/dcwapd.init
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
START=99
|
||||||
|
STOP=01
|
||||||
|
|
||||||
|
CONFIGURATION=dcwapd
|
||||||
|
VERBOSE=1
|
||||||
|
# NOTE: all functions write the result to the $result variable
|
||||||
|
result=
|
||||||
|
|
||||||
|
get_channelsets()
|
||||||
|
{
|
||||||
|
# default to empty
|
||||||
|
result=
|
||||||
|
channelsets=$(uci show $CONFIGURATION | grep "=channel-set$")
|
||||||
|
for channelset in $channelsets; do
|
||||||
|
channelset=$(echo "$channelset" | sed -rn "s/$CONFIGURATION\.(.*)=.*/\1/p")
|
||||||
|
result="$result $channelset"
|
||||||
|
done
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Channel Sets: $result" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the channel set name
|
||||||
|
get_channelset_enabled()
|
||||||
|
{
|
||||||
|
# default to disabled
|
||||||
|
result=0
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
result=$(uci get $CONFIGURATION."$1".enabled)
|
||||||
|
fi
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Channel Set \"$1\" Enabled: $result" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the channel set name
|
||||||
|
get_primary_bridge()
|
||||||
|
{
|
||||||
|
result=
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
result=$(uci get $CONFIGURATION."$1".bridge)
|
||||||
|
fi
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Channel Set \"$1\" Primary Bridge: $result" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the channel set name
|
||||||
|
get_datachannels()
|
||||||
|
{
|
||||||
|
# default to empty
|
||||||
|
result=
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
result=$(uci get $CONFIGURATION."$1".data_channels)
|
||||||
|
fi
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Channel Set \"$1\" Data Channels: $result" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the wlan interface name
|
||||||
|
get_wifi_iface_num()
|
||||||
|
{
|
||||||
|
result=
|
||||||
|
if [ -n "$1" ];then
|
||||||
|
#result=$(echo "$1" | sed -n "s/wlan//p")
|
||||||
|
result=$(echo "$1" | sed -rn "s/wlan([0-9]*).*/\1/p")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the bridge name
|
||||||
|
get_bridge_network_name()
|
||||||
|
{
|
||||||
|
result=
|
||||||
|
if [ -n "$1" ];then
|
||||||
|
result=$(echo "$1" | sed -n "s/br-//p")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the wlan interface name
|
||||||
|
set_iface_init_state()
|
||||||
|
{
|
||||||
|
result=
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
iface=$1
|
||||||
|
# need to extract the "X" from wlanX
|
||||||
|
get_wifi_iface_num "$iface"
|
||||||
|
iface_num=$result
|
||||||
|
if [ -n "$iface_num" ]; then
|
||||||
|
# get the iface network
|
||||||
|
init_net=$(uci get wireless.@wifi-iface[$iface_num].network)
|
||||||
|
if [ -n "$init_net" ]; then
|
||||||
|
# if the iface network is a bridge, but doesn't start with "br-"
|
||||||
|
# I think we need to prepend it?
|
||||||
|
net_type=$(uci get network."$init_net".type)
|
||||||
|
if [ -n "$net_type" ] && [ "$net_type" = "bridge" ]; then
|
||||||
|
prefix_ok=$(echo "$init_net" | grep "^br-")
|
||||||
|
if [ -z "$prefix_ok" ]; then
|
||||||
|
init_net="br-$init_net"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# make sure that the init_net section exists
|
||||||
|
init_net_section=$(uci get dcwapd.init_net)
|
||||||
|
if [ "$init_net_section" != "init_net" ]; then
|
||||||
|
# the section did not exist
|
||||||
|
uci set dcwapd.init_net=init_net
|
||||||
|
fi
|
||||||
|
|
||||||
|
# save the initial network
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Saving '$iface' initial network '$init_net'" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
uci set $CONFIGURATION.init_net."$iface"="$init_net"
|
||||||
|
uci commit
|
||||||
|
|
||||||
|
# save the initial network in the result variable
|
||||||
|
result=$init_net
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the wlan interface name
|
||||||
|
get_iface_init_state()
|
||||||
|
{
|
||||||
|
result=
|
||||||
|
if [ -n "$1" ];then
|
||||||
|
init_net=$(uci get $CONFIGURATION.init_net."$iface")
|
||||||
|
|
||||||
|
# if the response starts with "uci: ", it was an error not the real result
|
||||||
|
err=$(echo "$init_net" | grep "^uci: ")
|
||||||
|
if [ -z "$err" ]; then
|
||||||
|
# no error, set the result
|
||||||
|
result=$init_net
|
||||||
|
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Got '$iface' initial network '$init_net'" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the name of the data channel name to bring up
|
||||||
|
datachannel_up()
|
||||||
|
{
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
bridge=$(uci get $CONFIGURATION."$1".bridge)
|
||||||
|
interfaces=$(uci get $CONFIGURATION."$1".interfaces)
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Creating Data Channel Bridge: $bridge" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_bridge_network_name "$bridge"
|
||||||
|
netname=$result
|
||||||
|
if [ -n "$netname" ]; then
|
||||||
|
uci set network."$netname"=interface
|
||||||
|
uci set network."$netname".type=bridge
|
||||||
|
uci set network."$netname".proto=static
|
||||||
|
uci set network."$netname".bridge_empty='1'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create the bridge
|
||||||
|
uci commit
|
||||||
|
/etc/init.d/network reload
|
||||||
|
|
||||||
|
for iface in $interfaces; do
|
||||||
|
# if iface is in a bridge, the bridge name should be stored in result
|
||||||
|
set_iface_init_state "$iface"
|
||||||
|
init_bridge=$result
|
||||||
|
|
||||||
|
# update uci with the new bridge info
|
||||||
|
get_wifi_iface_num "$iface"
|
||||||
|
iface_num=$result
|
||||||
|
if [ -n "$iface_num" ]; then
|
||||||
|
uci set wireless.@wifi-iface[$iface_num].network="$netname"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# manually put the interface into the data bridge
|
||||||
|
# if iface is in a bridge, remove it before adding it to the data bridge
|
||||||
|
if [ -n "$init_bridge" ]; then
|
||||||
|
brctl delif "$init_bridge" "$iface" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
brctl addif "$bridge" "$iface" 2>&1 | logger
|
||||||
|
done
|
||||||
|
|
||||||
|
# commit uci changes and reload the network
|
||||||
|
uci commit
|
||||||
|
/etc/init.d/network reload
|
||||||
|
#/etc/init.d/network restart
|
||||||
|
# while [ 1 ]; do
|
||||||
|
# ifconfig "$bridge" > /dev/null 2>&1
|
||||||
|
# if [ $? == 0 ]; then
|
||||||
|
# break;
|
||||||
|
# fi
|
||||||
|
# sleep 1
|
||||||
|
# done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 : the name of the data channel to bring down
|
||||||
|
datachannel_down()
|
||||||
|
{
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
bridge=$(uci get $CONFIGURATION."$1".bridge)
|
||||||
|
interfaces=$(uci get $CONFIGURATION."$1".interfaces)
|
||||||
|
for iface in $interfaces; do
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Deconfiguring Data Channel Interface: $iface" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
|
||||||
|
# manually remove the interface from the data bridge
|
||||||
|
brctl delif "$bridge" "$iface" 2>&1 | logger
|
||||||
|
|
||||||
|
get_iface_init_state "$iface"
|
||||||
|
init_bridge=$result
|
||||||
|
if [ -n "$init_bridge" ]; then
|
||||||
|
# manually move the interface back to the original bridge
|
||||||
|
brctl addif "$init_bridge" "$iface" 2>&1 | logger
|
||||||
|
|
||||||
|
# update uci with the new bridge and interface configuration
|
||||||
|
get_wifi_iface_num "$iface"
|
||||||
|
iface_num=$result
|
||||||
|
get_bridge_network_name "$init_bridge"
|
||||||
|
netname=$result
|
||||||
|
if [ -n "$iface_num" ] && [ -n "$netname" ]; then
|
||||||
|
uci set wireless.@wifi-iface[$iface_num].network="$netname"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $VERBOSE -eq 1 ]; then
|
||||||
|
echo "Deconfiguring Data Channel Bridge: $bridge" 2>&1 | logger
|
||||||
|
fi
|
||||||
|
|
||||||
|
# delete the bridge from uci
|
||||||
|
get_bridge_network_name "$bridge"
|
||||||
|
netname=$result
|
||||||
|
if [ -n "$netname" ]; then
|
||||||
|
uci delete network."$netname"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# commit uci changes and reload the network
|
||||||
|
uci commit
|
||||||
|
/etc/init.d/network reload
|
||||||
|
#`/etc/init.d/network restart`
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
config_load "$CONFIGURATION"
|
||||||
|
local enabled
|
||||||
|
|
||||||
|
config_get enabled general enabled
|
||||||
|
if [ "$enabled" != "1" ]; then
|
||||||
|
echo "dcwapd is disabled in UCI"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_channelsets
|
||||||
|
# get the list of channel sets
|
||||||
|
channelsets=$result
|
||||||
|
|
||||||
|
for channelset in $channelsets; do
|
||||||
|
if [ -n "$channelset" ]; then
|
||||||
|
get_channelset_enabled "$channelset"
|
||||||
|
enabled=$result
|
||||||
|
if [ "$enabled" = "1" ]; then
|
||||||
|
# the channel set is enabled
|
||||||
|
|
||||||
|
# get the list of data channels used by the channel set
|
||||||
|
get_datachannels "$channelset"
|
||||||
|
datachannels=$result
|
||||||
|
for datachannel in $datachannels; do
|
||||||
|
datachannel_up "$datachannel"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
procd_open_instance
|
||||||
|
procd_set_param file /etc/config/dcwapd
|
||||||
|
procd_set_param command dcwapd
|
||||||
|
procd_set_param stdout 1
|
||||||
|
procd_set_param stderr 1
|
||||||
|
procd_close_instance
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
get_channelsets
|
||||||
|
# get the list of channel sets
|
||||||
|
channelsets=$result
|
||||||
|
|
||||||
|
for channelset in $channelsets; do
|
||||||
|
if [ -n "$channelset" ]; then
|
||||||
|
# we don't care if it is enabled, tear it down
|
||||||
|
# get_channelset_enabled $channelset
|
||||||
|
# enabled=$result
|
||||||
|
# if [ $enabled = "1" ]; then
|
||||||
|
# # the channel set is enabled
|
||||||
|
|
||||||
|
# get the list of data channels used by the channel set
|
||||||
|
get_datachannels "$channelset"
|
||||||
|
datachannels=$result
|
||||||
|
for datachannel in $datachannels; do
|
||||||
|
datachannel_down "$datachannel"
|
||||||
|
done
|
||||||
|
# fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
}
|
||||||
|
|
||||||
|
service_triggers()
|
||||||
|
{
|
||||||
|
procd_add_reload_trigger dcwapd
|
||||||
|
}
|
||||||
|
|
||||||
|
reload_service() {
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
}
|
32
net/dcwapd/files/dcwapd.uci
Normal file
32
net/dcwapd/files/dcwapd.uci
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
config general 'general'
|
||||||
|
option enabled 0
|
||||||
|
option tmpdir '/tmp/dcwapd'
|
||||||
|
|
||||||
|
config channel-set 'channelset0'
|
||||||
|
option enabled 0
|
||||||
|
option ssid 'OpenWrt'
|
||||||
|
option bridge 'br-lan'
|
||||||
|
option data_channels 'datachannel0'
|
||||||
|
|
||||||
|
config datachannel 'datachannel0'
|
||||||
|
option ssid 'OpenWrt-DCW'
|
||||||
|
option bridge 'br-dc0'
|
||||||
|
option interfaces ''
|
||||||
|
|
||||||
|
config filter-set 'TFP_Default'
|
||||||
|
option mac '*'
|
||||||
|
option filters 'filter0 filter1'
|
||||||
|
|
||||||
|
config filter 'filter0'
|
||||||
|
option packet_size '*'
|
||||||
|
option source_ip '*'
|
||||||
|
option source_port '80'
|
||||||
|
option protocol 'tcp'
|
||||||
|
option dest_port '*'
|
||||||
|
|
||||||
|
config filter 'filter1'
|
||||||
|
option packet_size '*'
|
||||||
|
option source_ip '*'
|
||||||
|
option source_port '443'
|
||||||
|
option protocol 'tcp'
|
||||||
|
option dest_port '*'
|
475
net/dcwapd/patches/01_add_uci_config_provider.patch
Normal file
475
net/dcwapd/patches/01_add_uci_config_provider.patch
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
--- a/dev/null
|
||||||
|
+++ b/dcwlinux/uci_configuration_provider.h
|
||||||
|
@@ -0,0 +1,104 @@
|
||||||
|
+#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
|
||||||
|
+#define UCI_CONFIGURATION_PROVIDER_H_INCLUDED
|
||||||
|
+
|
||||||
|
+#include "./ap_configuration.h"
|
||||||
|
+
|
||||||
|
+namespace dcwlinux {
|
||||||
|
+
|
||||||
|
+class UciConfigurationProvider : public APConfigurationProvider {
|
||||||
|
+
|
||||||
|
+ static const char *SECTION_TYPE_GENERAL;
|
||||||
|
+ static const char *SECTION_TYPE_CHANNEL_SET;
|
||||||
|
+ static const char *SECTION_TYPE_DATA_CHANNEL;
|
||||||
|
+ static const char *SECTION_TYPE_FILTER_SET;
|
||||||
|
+ static const char *SECTION_TYPE_FILTER;
|
||||||
|
+ static const char *DEFAULT_FILTER_SET_NAME;
|
||||||
|
+
|
||||||
|
+ static const char *OPTION_TMPDIR;
|
||||||
|
+ static const char *OPTION_ENABLED;
|
||||||
|
+ static const char *OPTION_SSID;
|
||||||
|
+ static const char *OPTION_BRIDGE;
|
||||||
|
+ static const char *OPTION_DATA_CHANNELS;
|
||||||
|
+ static const char *OPTION_INTERFACES;
|
||||||
|
+ static const char *OPTION_MAC_ADDRESS;
|
||||||
|
+ static const char *OPTION_FILTERS;
|
||||||
|
+ static const char *OPTION_PACKET_SIZE;
|
||||||
|
+ static const char *OPTION_SOURCE_IP;
|
||||||
|
+ static const char *OPTION_SOURCE_PORT;
|
||||||
|
+ static const char *OPTION_PROTOCOL;
|
||||||
|
+ static const char *OPTION_DEST_PORT;
|
||||||
|
+
|
||||||
|
+ static const char *FILTER_FILE_EXTENSION;
|
||||||
|
+
|
||||||
|
+ UciConfigurationProvider(const UciConfigurationProvider&); //no copy
|
||||||
|
+
|
||||||
|
+ typedef std::map<std::string, std::string> DataChannelBridgeMap;
|
||||||
|
+ struct PrimaryChannel {
|
||||||
|
+ std::string bridgeName;
|
||||||
|
+ DataChannelBridgeMap dataChannels;
|
||||||
|
+ };
|
||||||
|
+ typedef std::map<std::string, PrimaryChannel> PrimaryChannelMap;
|
||||||
|
+ typedef std::map<dcw::MacAddress, std::string> StationFilterMap;
|
||||||
|
+
|
||||||
|
+ struct uci_context *_uciContext;
|
||||||
|
+ struct uci_package *_uciPackage;
|
||||||
|
+ const char *_uciConfig;
|
||||||
|
+
|
||||||
|
+ std::string _filterDirectory;
|
||||||
|
+ PrimaryChannelMap _primaryChannels;
|
||||||
|
+ StationFilterMap _stationFilters;
|
||||||
|
+
|
||||||
|
+public:
|
||||||
|
+ UciConfigurationProvider(const char * const uciConfig); // the "config" part of UCI commands
|
||||||
|
+ virtual ~UciConfigurationProvider();
|
||||||
|
+
|
||||||
|
+ virtual void InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const;
|
||||||
|
+ virtual void GetPrimarySsids(SsidSet& output) const;
|
||||||
|
+ virtual void GetDataSsids(SsidSet& output, const char * const primarySsid) const;
|
||||||
|
+ virtual const char *GetSsidIfname(const char * const ssid) const;
|
||||||
|
+ virtual void GetStationTrafficFilterProfiles(StationTFPMap& output) const;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+}; //namespace dcwlinux {
|
||||||
|
+
|
||||||
|
+#endif //#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
|
||||||
|
+#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
|
||||||
|
+#define UCI_CONFIGURATION_PROVIDER_H_INCLUDED
|
||||||
|
+
|
||||||
|
+#include "./ap_configuration.h"
|
||||||
|
+
|
||||||
|
+namespace dcwlinux {
|
||||||
|
+
|
||||||
|
+class UciConfigurationProvider : public APConfigurationProvider {
|
||||||
|
+ UciConfigurationProvider(const UciConfigurationProvider&); //no copy
|
||||||
|
+
|
||||||
|
+ typedef std::map<std::string, std::string> DataChannelBridgeMap;
|
||||||
|
+ struct PrimaryChannel {
|
||||||
|
+ std::string bridgeName;
|
||||||
|
+ DataChannelBridgeMap dataChannels;
|
||||||
|
+ };
|
||||||
|
+ typedef std::map<std::string, PrimaryChannel> PrimaryChannelMap;
|
||||||
|
+ typedef std::map<dcw::MacAddress, std::string> StationFilterMap;
|
||||||
|
+
|
||||||
|
+ struct uci_context *_uciContext;
|
||||||
|
+ struct uci_package *_uciPackage;
|
||||||
|
+ const char *_uciConfig;
|
||||||
|
+
|
||||||
|
+ PrimaryChannelMap _primaryChannels;
|
||||||
|
+ StationFilterMap _stationFilters;
|
||||||
|
+ CFTFPList _defaultFilters;
|
||||||
|
+
|
||||||
|
+public:
|
||||||
|
+ UciConfigurationProvider(const char * const uciConfig); // the "config" part of UCI commands
|
||||||
|
+ virtual ~UciConfigurationProvider();
|
||||||
|
+
|
||||||
|
+ virtual void InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const;
|
||||||
|
+ virtual void GetPrimarySsids(SsidSet& output) const;
|
||||||
|
+ virtual void GetDataSsids(SsidSet& output, const char * const primarySsid) const;
|
||||||
|
+ virtual const char *GetSsidIfname(const char * const ssid) const;
|
||||||
|
+ virtual void GetStationTrafficFilterProfiles(StationTFPMap& output) const;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+}; //namespace dcwlinux {
|
||||||
|
+
|
||||||
|
+#endif //#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
|
||||||
|
--- a/dev/null
|
||||||
|
+++ b/dcwlinux/uci_configuration_provider.cxx
|
||||||
|
@@ -0,0 +1,365 @@
|
||||||
|
+
|
||||||
|
+#include <uci.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdexcept>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <cerrno>
|
||||||
|
+#include <iostream>
|
||||||
|
+#include <fstream>
|
||||||
|
+
|
||||||
|
+#include "./uci_configuration_provider.h"
|
||||||
|
+
|
||||||
|
+#include "dcwposix/filterdirscanner.h"
|
||||||
|
+#include "dcw/macaddress.h"
|
||||||
|
+#include "dcw/dcwlog.h"
|
||||||
|
+
|
||||||
|
+using namespace dcwlinux;
|
||||||
|
+
|
||||||
|
+ const char *UciConfigurationProvider::SECTION_TYPE_GENERAL = "general";
|
||||||
|
+ const char *UciConfigurationProvider::SECTION_TYPE_CHANNEL_SET = "channel-set";
|
||||||
|
+ const char *UciConfigurationProvider::SECTION_TYPE_DATA_CHANNEL = "datachannel";
|
||||||
|
+ const char *UciConfigurationProvider::SECTION_TYPE_FILTER_SET = "filter-set";
|
||||||
|
+ const char *UciConfigurationProvider::SECTION_TYPE_FILTER = "filter";
|
||||||
|
+ const char *UciConfigurationProvider::DEFAULT_FILTER_SET_NAME = "TFP_Default";
|
||||||
|
+
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_TMPDIR = "tmpdir";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_ENABLED = "enabled";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_SSID = "ssid";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_BRIDGE = "bridge";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_DATA_CHANNELS = "data_channels";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_INTERFACES = "interfaces";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_MAC_ADDRESS = "mac";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_FILTERS = "filters";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_PACKET_SIZE = "packet_size";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_SOURCE_IP = "source_ip";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_SOURCE_PORT = "source_port";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_PROTOCOL = "protocol";
|
||||||
|
+ const char *UciConfigurationProvider::OPTION_DEST_PORT = "dest_port";
|
||||||
|
+
|
||||||
|
+ const char *UciConfigurationProvider::FILTER_FILE_EXTENSION = ".tfp";
|
||||||
|
+
|
||||||
|
+ UciConfigurationProvider::UciConfigurationProvider(const char * const uciConfig) : _uciConfig(uciConfig) {
|
||||||
|
+
|
||||||
|
+ //printf("*** Start UciConfigurationProvider(%s)\n", _uciConfig);
|
||||||
|
+ //printf("*** About to uci_alloc_context()\n");
|
||||||
|
+
|
||||||
|
+ _uciContext = uci_alloc_context();
|
||||||
|
+
|
||||||
|
+ //printf("*** uci_alloc_context() complete\n");
|
||||||
|
+ //printf("*** About to uci_load()\n");
|
||||||
|
+
|
||||||
|
+ if (_uciContext == NULL)
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error creating UCI context ";
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uci_load(_uciContext, _uciConfig, &_uciPackage);
|
||||||
|
+
|
||||||
|
+ //printf("*** uci_load complete()\n");
|
||||||
|
+
|
||||||
|
+ if (_uciPackage == NULL)
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error loading UCI package " + std::string(_uciConfig);
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uci_section *generalSection = uci_lookup_section(_uciContext, _uciPackage, UciConfigurationProvider::SECTION_TYPE_GENERAL);
|
||||||
|
+ if (generalSection == NULL)
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error: A general section (" + std::string(UciConfigurationProvider::SECTION_TYPE_GENERAL) + ") must be specified!";
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uci_option *opt_tmpdir = uci_lookup_option(_uciContext, generalSection, UciConfigurationProvider::OPTION_TMPDIR);
|
||||||
|
+ if (opt_tmpdir == NULL)
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error: A temporary directory (" + std::string(UciConfigurationProvider::OPTION_TMPDIR) + ") must be specified!";
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+ char *tmpdir = opt_tmpdir->v.string;
|
||||||
|
+ //printf(" *** Set tmpdir: %s\n", tmpdir);
|
||||||
|
+
|
||||||
|
+ // make sure that tmpdir exists
|
||||||
|
+ int status = mkdir(tmpdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
|
+ if ((status != 0) && // failure
|
||||||
|
+ (errno != EEXIST)) // the failure was not that the directory already existed
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error: Unable to create the temporary directory (tmpdir), error # " + errno;
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+ _filterDirectory = std::string(tmpdir);
|
||||||
|
+
|
||||||
|
+ if (uci_lookup_section(_uciContext, _uciPackage, UciConfigurationProvider::DEFAULT_FILTER_SET_NAME) == NULL)
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error: A default traffic filter profile named " + std::string(UciConfigurationProvider::DEFAULT_FILTER_SET_NAME) + " MUST exist!";
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // iterate over all of the sections in the package
|
||||||
|
+ uci_element *elem;
|
||||||
|
+ uci_foreach_element(&_uciPackage->sections, elem)
|
||||||
|
+ {
|
||||||
|
+ //printf("--==-- element.type: %d\n", elem->type);
|
||||||
|
+ //printf("--==-- element.name: %s\n", elem->name);
|
||||||
|
+
|
||||||
|
+ if (elem->type == UCI_TYPE_SECTION)
|
||||||
|
+ {
|
||||||
|
+ // look up the section and get it's type
|
||||||
|
+
|
||||||
|
+ uci_section *section = NULL;
|
||||||
|
+ //printf("*** Looking up section: %s\n", elem->name);
|
||||||
|
+
|
||||||
|
+ section = uci_lookup_section(_uciContext, _uciPackage, elem->name);
|
||||||
|
+
|
||||||
|
+ if ((section != NULL) && (section->type != NULL))
|
||||||
|
+ {
|
||||||
|
+ //printf(" *** Section type: %s\n", section->type);
|
||||||
|
+ if (strcmp(elem->name, UciConfigurationProvider::SECTION_TYPE_GENERAL) == 0)
|
||||||
|
+ {
|
||||||
|
+ // we already processed the general section for the tmpdir
|
||||||
|
+ }
|
||||||
|
+ else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_CHANNEL_SET) == 0)
|
||||||
|
+ {
|
||||||
|
+ // the section is a channel set, populate it with the specified values
|
||||||
|
+
|
||||||
|
+ uci_option *enabled = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_ENABLED);
|
||||||
|
+ if ((enabled == NULL) || (strcmp(enabled->v.string, "1") != 0))
|
||||||
|
+ {
|
||||||
|
+ // found a disabled channel set, ignore it
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uci_option *ssid = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_SSID);
|
||||||
|
+ uci_option *bridge = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_BRIDGE);
|
||||||
|
+ uci_option *dataChannels = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_DATA_CHANNELS);
|
||||||
|
+
|
||||||
|
+ if ((ssid != NULL) && (bridge != NULL) && (dataChannels != NULL))
|
||||||
|
+ {
|
||||||
|
+ PrimaryChannel &pc = _primaryChannels[ssid->v.string];
|
||||||
|
+ pc.bridgeName = bridge->v.string;
|
||||||
|
+
|
||||||
|
+ char dataChannels_list[255];
|
||||||
|
+ // The dataChannels option is not a list
|
||||||
|
+ //if (dataChannels->type == UCI_TYPE_LIST)
|
||||||
|
+ if (dataChannels->v.string != NULL)
|
||||||
|
+ {
|
||||||
|
+ strcpy(dataChannels_list, dataChannels->v.string);
|
||||||
|
+ std::string str_dataChannels = dataChannels->v.string;
|
||||||
|
+ size_t start_pos = 0;
|
||||||
|
+ size_t pos = 0;
|
||||||
|
+ while(start_pos != std::string::npos)
|
||||||
|
+ {
|
||||||
|
+ pos = str_dataChannels.find(" ", start_pos);
|
||||||
|
+ //printf("****** start_pos: %u, pos: %u\n", start_pos, pos);
|
||||||
|
+ std::string str_dataChannel = str_dataChannels.substr(start_pos,
|
||||||
|
+ pos == std::string::npos ? pos : pos-start_pos);
|
||||||
|
+ //printf("*** dataChannel: %s\n", str_dataChannel.c_str());
|
||||||
|
+
|
||||||
|
+ // update the start position for next loop
|
||||||
|
+ start_pos = (pos == std::string::npos ? pos : pos+1);
|
||||||
|
+
|
||||||
|
+ uci_section *dcSection = uci_lookup_section(_uciContext, _uciPackage, str_dataChannel.c_str());
|
||||||
|
+ if (dcSection != NULL)
|
||||||
|
+ {
|
||||||
|
+ uci_option *dcSsid = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_SSID);
|
||||||
|
+ uci_option *dcBridge = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_BRIDGE);
|
||||||
|
+
|
||||||
|
+ // TODO: configure dcBridge and dcInterfaces
|
||||||
|
+ //uci_option *dcInterfaces = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_INTERFACES);
|
||||||
|
+
|
||||||
|
+ if ((dcSsid != NULL) && (dcBridge != NULL))
|
||||||
|
+ {
|
||||||
|
+ pc.dataChannels[dcSsid->v.string];
|
||||||
|
+ pc.dataChannels[dcSsid->v.string] = dcBridge->v.string;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //printf("Section: %s, SSID: %s, Bridge: %s, Data Channels: %s\n", section->e.name, ssid->v.string, bridge->v.string, dataChannels_list);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_DATA_CHANNEL) == 0)
|
||||||
|
+ {
|
||||||
|
+ // data channels are processed by the channel set
|
||||||
|
+ }
|
||||||
|
+ else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_FILTER_SET) == 0)
|
||||||
|
+ {
|
||||||
|
+ // the section is a filter set, populate it with the specified values
|
||||||
|
+ //printf("*** filter set: %s\n", elem->name);
|
||||||
|
+
|
||||||
|
+ // create a tfp file for the sectionName
|
||||||
|
+ std::ofstream tfpFile;
|
||||||
|
+ std::string tfpFilePath =
|
||||||
|
+ tmpdir + std::string("/") +
|
||||||
|
+ std::string(elem->name) +
|
||||||
|
+ std::string(UciConfigurationProvider::FILTER_FILE_EXTENSION);
|
||||||
|
+ tfpFile.open(tfpFilePath.c_str(), std::ios::out | std::ios::trunc);
|
||||||
|
+ if (!tfpFile.is_open())
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error: Unable to open the filter file: " + tfpFilePath;
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ const char *filterDelimiter = "\n";
|
||||||
|
+ char sFilterContents[2048];
|
||||||
|
+ sFilterContents[0] = '\0';
|
||||||
|
+
|
||||||
|
+ uci_option *filters = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_FILTERS);
|
||||||
|
+ // The filters option is not a list
|
||||||
|
+ //if ((filters != NULL) && (filters->type == UCI_TYPE_LIST))
|
||||||
|
+ if (filters != NULL)
|
||||||
|
+ {
|
||||||
|
+ //printf("*** %s.filters is a list.\n", elem->name);
|
||||||
|
+ //struct uci_element *e;
|
||||||
|
+ //uci_foreach_element(&filters->v.list, e)
|
||||||
|
+
|
||||||
|
+ std::string str_filters = filters->v.string;
|
||||||
|
+ //printf("*** STR_FILTERS: %s\n", str_filters.c_str());
|
||||||
|
+ size_t start_pos = 0;
|
||||||
|
+ size_t pos = 0;
|
||||||
|
+ while(start_pos != std::string::npos)
|
||||||
|
+ {
|
||||||
|
+ pos = str_filters.find(" ", start_pos);
|
||||||
|
+ //printf("****** start_pos: %u, pos: %u\n", start_pos, pos);
|
||||||
|
+ std::string str_filter = str_filters.substr(start_pos,
|
||||||
|
+ pos == std::string::npos ? pos : pos-start_pos);
|
||||||
|
+ //printf("*** Looking for filter section named: %s ...\n", str_filter.c_str());
|
||||||
|
+
|
||||||
|
+ // update the start position for next loop
|
||||||
|
+ start_pos = (pos == std::string::npos ? pos : pos+1);
|
||||||
|
+
|
||||||
|
+ uci_section *fSection = uci_lookup_section(_uciContext, _uciPackage, str_filter.c_str());
|
||||||
|
+ if (fSection != NULL)
|
||||||
|
+ {
|
||||||
|
+ uci_option *fPacketSize = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_PACKET_SIZE);
|
||||||
|
+ uci_option *fSourceIp = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_SOURCE_IP);
|
||||||
|
+ uci_option *fSourcePort = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_SOURCE_PORT);
|
||||||
|
+ uci_option *fProtocol = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_PROTOCOL);
|
||||||
|
+ uci_option *fDestPort = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_DEST_PORT);
|
||||||
|
+
|
||||||
|
+ if ((fPacketSize != NULL) &&
|
||||||
|
+ (fSourceIp != NULL) &&
|
||||||
|
+ (fSourcePort != NULL) &&
|
||||||
|
+ (fProtocol != NULL) &&
|
||||||
|
+ (fDestPort != NULL))
|
||||||
|
+ {
|
||||||
|
+ //printf("*** filter: %s %s:%s:%s:%s:%s\n", e->name,
|
||||||
|
+ // fPacketSize->v.string, fSourceIp->v.string, fSourcePort->v.string,
|
||||||
|
+ // fProtocol->v.string, fDestPort->v.string);
|
||||||
|
+
|
||||||
|
+ strcpy(sFilterContents, fPacketSize->v.string);
|
||||||
|
+ strcat(sFilterContents, ":");
|
||||||
|
+ strcat(sFilterContents, fSourceIp->v.string);
|
||||||
|
+ strcat(sFilterContents, ":");
|
||||||
|
+ strcat(sFilterContents, fSourcePort->v.string);
|
||||||
|
+ strcat(sFilterContents, ":");
|
||||||
|
+ strcat(sFilterContents, fProtocol->v.string);
|
||||||
|
+ strcat(sFilterContents, ":");
|
||||||
|
+ strcat(sFilterContents, fDestPort->v.string);
|
||||||
|
+ strcat(sFilterContents, filterDelimiter);
|
||||||
|
+
|
||||||
|
+ //printf("*** Writing filter contents to file: %s\n", sFilterContents);
|
||||||
|
+ tfpFile << sFilterContents;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ std::string err = "Error parsing filter: " + str_filter;
|
||||||
|
+ throw std::runtime_error(err);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ tfpFile.close();
|
||||||
|
+
|
||||||
|
+ // if there is a MAC address for the filter set, we need to add it to the station filters list
|
||||||
|
+ uci_option *mac = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_MAC_ADDRESS);
|
||||||
|
+ if (mac != NULL)
|
||||||
|
+ {
|
||||||
|
+ // ignore wildcard MAC address
|
||||||
|
+ if (strcmp(mac->v.string,"*") != 0)
|
||||||
|
+ {
|
||||||
|
+ //printf(" *** MAC Address: %s\n", mac->v.string);
|
||||||
|
+ _stationFilters[::dcw::MacAddress(mac->v.string)] = elem->name;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_FILTER) == 0)
|
||||||
|
+ {
|
||||||
|
+ // filters are processed by the filter set
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ //std::string err = "Error: Unknown UCI section type: " + std::string(section->type);
|
||||||
|
+ //throw std::runtime_error(err);
|
||||||
|
+
|
||||||
|
+ // Don't throw an exception. It is fine for UCI to contain things that we do not know about
|
||||||
|
+ // that it may use for other purposes, like UI or internal state
|
||||||
|
+ dcwlogdbgf("Ignoring UCI section type: %s\n", section->type);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ UciConfigurationProvider::~UciConfigurationProvider() {
|
||||||
|
+ uci_free_context(_uciContext);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void UciConfigurationProvider::InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const {
|
||||||
|
+ ::dcwposix::FilterdirScanner::FileFilterProfileList ffpl;
|
||||||
|
+ ::dcwposix::FilterdirScanner dirScanner(_filterDirectory.c_str());
|
||||||
|
+ dirScanner.Scan(ffpl);
|
||||||
|
+
|
||||||
|
+ for (::dcwposix::FilterdirScanner::FileFilterProfileList::const_iterator i = ffpl.begin(); i != ffpl.end(); i++) {
|
||||||
|
+ output.push_back(new ::dcw::FileTrafficFilterProfile(*i));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ void UciConfigurationProvider::GetPrimarySsids(SsidSet& output) const {
|
||||||
|
+ for (PrimaryChannelMap::const_iterator i = _primaryChannels.begin(); i != _primaryChannels.end(); i++) {
|
||||||
|
+ output.insert(i->first);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void UciConfigurationProvider::GetDataSsids(SsidSet& output, const char * const primarySsid) const {
|
||||||
|
+ const PrimaryChannelMap::const_iterator pssid = _primaryChannels.find(primarySsid);
|
||||||
|
+ if (pssid == _primaryChannels.end()) return;
|
||||||
|
+
|
||||||
|
+ for (DataChannelBridgeMap::const_iterator i = pssid->second.dataChannels.begin(); i != pssid->second.dataChannels.end(); i++) {
|
||||||
|
+ output.insert(i->first);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ const char *UciConfigurationProvider::GetSsidIfname(const char * const ssid) const {
|
||||||
|
+ PrimaryChannelMap::const_iterator pssid = _primaryChannels.find(ssid);
|
||||||
|
+ if (pssid != _primaryChannels.end()) {
|
||||||
|
+ if (pssid->second.bridgeName.empty()) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ return pssid->second.bridgeName.c_str();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (pssid = _primaryChannels.begin(); pssid != _primaryChannels.end(); pssid++) {
|
||||||
|
+ const DataChannelBridgeMap& dataChannels = pssid->second.dataChannels;
|
||||||
|
+ const DataChannelBridgeMap::const_iterator dc = dataChannels.find(ssid);
|
||||||
|
+ if (dc == dataChannels.end()) continue;
|
||||||
|
+ if (dc->second.empty()) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ return dc->second.c_str();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ void UciConfigurationProvider::GetStationTrafficFilterProfiles(StationTFPMap& output) const {
|
||||||
|
+ for (StationFilterMap::const_iterator i = _stationFilters.begin(); i != _stationFilters.end(); i++) {
|
||||||
|
+ output[i->first] = i->second;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
20
net/dcwapd/patches/02_use_uci_config_provider.patch
Normal file
20
net/dcwapd/patches/02_use_uci_config_provider.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--- a/dcwapd.linuxjsonstatic/main.cxx
|
||||||
|
+++ b/dcwapd.linuxjsonstatic/main.cxx
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include "dcwlinux/ap_configuration.h"
|
||||||
|
#include "dcwlinux/vap_manager.h"
|
||||||
|
#include "dcwlinux/json_configuration_provider.h"
|
||||||
|
+#include "dcwlinux/uci_configuration_provider.h"
|
||||||
|
|
||||||
|
#include "dcw/dcwlog.h"
|
||||||
|
|
||||||
|
@@ -19,7 +20,8 @@ int
|
||||||
|
main( void ) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
- dcwlinux::JsonConfigurationProvider configProvider("./dcwapdconf.json");
|
||||||
|
+ //dcwlinux::JsonConfigurationProvider configProvider("./dcwapdconf.json");
|
||||||
|
+ dcwlinux::UciConfigurationProvider configProvider("dcwapd");
|
||||||
|
|
||||||
|
dcwposix::ProcessSignalManager sigman;
|
||||||
|
dcwposix::SelectEventReactor eventReactor;
|
@ -0,0 +1,10 @@
|
|||||||
|
--- a/dcwlinux/Makefile.am
|
||||||
|
+++ b/dcwlinux/Makefile.am
|
||||||
|
@@ -6,6 +6,7 @@ libdcwlinux_la_SOURCES =
|
||||||
|
ap_configuration.cxx \
|
||||||
|
brctlnetwork.cxx \
|
||||||
|
json_configuration_provider.cxx \
|
||||||
|
+ uci_configuration_provider.cxx \
|
||||||
|
macremapper_driver.cxx \
|
||||||
|
vap_manager.cxx \
|
||||||
|
virtual_ap.cxx
|
15
net/modemmanager/Config.in
Normal file
15
net/modemmanager/Config.in
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
menu "Configuration"
|
||||||
|
depends on PACKAGE_modemmanager
|
||||||
|
|
||||||
|
config MODEMMANAGER_WITH_MBIM
|
||||||
|
bool "Include MBIM support"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Compile ModemManager with MBIM support
|
||||||
|
|
||||||
|
config MODEMMANAGER_WITH_QMI
|
||||||
|
bool "Include QMI support"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Compile ModemManager with QMI support
|
||||||
|
endmenu
|
140
net/modemmanager/Makefile
Normal file
140
net/modemmanager/Makefile
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016 Velocloud Inc.
|
||||||
|
# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=modemmanager
|
||||||
|
PKG_VERSION:=1.12.0
|
||||||
|
PKG_RELEASE:=8
|
||||||
|
|
||||||
|
PKG_SOURCE:=ModemManager-$(PKG_VERSION).tar.xz
|
||||||
|
PKG_SOURCE_URL:=https://www.freedesktop.org/software/ModemManager
|
||||||
|
PKG_HASH:=3daca86164145fffb589939433f596c13fa077c9a187c0d5820fdd5b4e4a6424
|
||||||
|
PKG_BUILD_DIR:=$(BUILD_DIR)/ModemManager-$(PKG_VERSION)
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Nicholas Smith <nicholas.smith@telcoantennas.com.au>
|
||||||
|
LICENSE:=GPL-2.0-or-later
|
||||||
|
LICENSE_FILES:=COPYING
|
||||||
|
|
||||||
|
PKG_INSTALL:=1
|
||||||
|
PKG_BUILD_PARALLEL:=1
|
||||||
|
|
||||||
|
PKG_BUILD_DEPENDS:=glib2/host libxslt/host
|
||||||
|
|
||||||
|
PKG_FIXUP:=autoreconf
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/modemmanager/config
|
||||||
|
source "$(SOURCE)/Config.in"
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/modemmanager
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
TITLE:=Control utility for any kind of mobile broadband modem
|
||||||
|
URL:=https://www.freedesktop.org/wiki/Software/ModemManager
|
||||||
|
DEPENDS:= \
|
||||||
|
$(INTL_DEPENDS) \
|
||||||
|
+glib2 \
|
||||||
|
+dbus \
|
||||||
|
+MODEMMANAGER_WITH_MBIM:libmbim \
|
||||||
|
+MODEMMANAGER_WITH_QMI:libqmi
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/modemmanager/description
|
||||||
|
ModemManager is a D-Bus-activated service which allows controlling mobile
|
||||||
|
broadband modems. Add kernel modules for your modems as needed.
|
||||||
|
Select Utilities/usb-modeswitch if needed.
|
||||||
|
endef
|
||||||
|
|
||||||
|
CONFIGURE_ARGS += \
|
||||||
|
--without-polkit \
|
||||||
|
--without-udev \
|
||||||
|
--without-suspend-resume \
|
||||||
|
--with-systemdsystemunitdir=no \
|
||||||
|
--disable-rpath \
|
||||||
|
--disable-gtk-doc
|
||||||
|
|
||||||
|
ifdef CONFIG_MODEMMANAGER_WITH_MBIM
|
||||||
|
CONFIGURE_ARGS += --with-mbim
|
||||||
|
else
|
||||||
|
CONFIGURE_ARGS += --without-mbim
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_MODEMMANAGER_WITH_QMI
|
||||||
|
CONFIGURE_ARGS += --with-qmi
|
||||||
|
else
|
||||||
|
CONFIGURE_ARGS += --without-qmi
|
||||||
|
endif
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
$(call Build/Prepare/Default)
|
||||||
|
( cd "$(PKG_BUILD_DIR)"; \
|
||||||
|
printf "all:\ninstall:\n" >po/Makefile.in.in; \
|
||||||
|
)
|
||||||
|
$(SED) 's|^\(GLIB_MKENUMS\)=.*|\1=$(STAGING_DIR_HOSTPKG)/bin/glib-mkenums|' \
|
||||||
|
$(PKG_BUILD_DIR)/configure.ac
|
||||||
|
$(SED) 's|^\(GDBUS_CODEGEN\)=.*|\1=$(STAGING_DIR_HOSTPKG)/bin/gdbus-codegen|' \
|
||||||
|
$(PKG_BUILD_DIR)/configure.ac
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/InstallDev
|
||||||
|
$(INSTALL_DIR) $(1)/usr/include/ModemManager
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/include/ModemManager/*.h $(1)/usr/include/ModemManager
|
||||||
|
$(INSTALL_DIR) $(1)/usr/include/libmm-glib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/include/libmm-glib/*.h $(1)/usr/include/libmm-glib
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmm-glib.so* $(1)/usr/lib
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/ModemManager.pc $(1)/usr/lib/pkgconfig
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/mm-glib.pc $(1)/usr/lib/pkgconfig
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/modemmanager/install
|
||||||
|
$(INSTALL_DIR) $(1)/lib/udev/rules.d
|
||||||
|
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/lib/udev/rules.d/*.rules $(1)/lib/udev/rules.d
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ModemManager $(1)/usr/sbin
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mmcli $(1)/usr/bin
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmm-glib.so.* $(1)/usr/lib
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib/ModemManager
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/ModemManager/libmm-plugin-*.so* $(1)/usr/lib/ModemManager
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/dbus-1/system.d
|
||||||
|
$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/dbus-1/system.d/org.freedesktop.ModemManager1.conf $(1)/etc/dbus-1/system.d
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/share/dbus-1/system-services
|
||||||
|
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/dbus-1/system-services/org.freedesktop.ModemManager1.service $(1)/usr/share/dbus-1/system-services
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/share/ModemManager
|
||||||
|
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/ModemManager/*.conf $(1)/usr/share/ModemManager
|
||||||
|
$(INSTALL_DATA) ./files/modemmanager.common $(1)/usr/share/ModemManager
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/modemmanager.init $(1)/etc/init.d/modemmanager
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/hotplug.d/usb
|
||||||
|
$(INSTALL_DATA) ./files/25-modemmanager-usb $(1)/etc/hotplug.d/usb
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/hotplug.d/net
|
||||||
|
$(INSTALL_DATA) ./files/25-modemmanager-net $(1)/etc/hotplug.d/net
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/hotplug.d/tty
|
||||||
|
$(INSTALL_DATA) ./files/25-modemmanager-tty $(1)/etc/hotplug.d/tty
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||||
|
$(INSTALL_BIN) ./files/modemmanager.proto $(1)/lib/netifd/proto/modemmanager.sh
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,modemmanager))
|
22
net/modemmanager/README.md
Normal file
22
net/modemmanager/README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# OpenWrt ModemManager
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Cellular modem control and connectivity
|
||||||
|
|
||||||
|
Optional libraries libmbim and libqmi are available. Optional mbim-utils and qmi-utils are available.
|
||||||
|
Your modem may require additional kernel modules.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
# Once installed, you can configure the 2G/3G/4G modem connections directly in
|
||||||
|
/etc/config/network as in the following example:
|
||||||
|
|
||||||
|
config interface 'broadband'
|
||||||
|
option device '/sys/devices/platform/soc/20980000.usb/usb1/1-1/1-1.2/1-1.2.1'
|
||||||
|
option proto 'modemmanager'
|
||||||
|
option apn 'ac.vodafone.es'
|
||||||
|
option username 'vodafone'
|
||||||
|
option password 'vodafone'
|
||||||
|
option pincode '7423'
|
||||||
|
option lowpower '1'
|
31
net/modemmanager/files/25-modemmanager-net
Normal file
31
net/modemmanager/files/25-modemmanager-net
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (C) 2016 Velocloud Inc
|
||||||
|
# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
|
||||||
|
# Load common utilities
|
||||||
|
. /usr/share/ModemManager/modemmanager.common
|
||||||
|
|
||||||
|
# We require a interface name
|
||||||
|
[ -n "${INTERFACE}" ] || exit
|
||||||
|
|
||||||
|
# Always make sure the rundir exists
|
||||||
|
mkdir -m 0755 -p "${MODEMMANAGER_RUNDIR}"
|
||||||
|
|
||||||
|
# Report network interface
|
||||||
|
mm_log "${ACTION} network interface ${INTERFACE}: event processed"
|
||||||
|
mm_report_event "${ACTION}" "${INTERFACE}" "net" "/sys${DEVPATH}"
|
||||||
|
|
||||||
|
# Look for an associated cdc-wdm interface
|
||||||
|
|
||||||
|
cdcwdm=""
|
||||||
|
|
||||||
|
case "${ACTION}" in
|
||||||
|
"add") cdcwdm=$(mm_track_cdcwdm "${INTERFACE}") ;;
|
||||||
|
"remove") cdcwdm=$(mm_untrack_cdcwdm "${INTERFACE}") ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Report cdc-wdm device, if any
|
||||||
|
[ -n "${cdcwdm}" ] && {
|
||||||
|
mm_log "${ACTION} cdc interface ${cdcwdm}: custom event processed"
|
||||||
|
mm_report_event "${ACTION}" "${cdcwdm}" "usbmisc" "/sys${DEVPATH}"
|
||||||
|
}
|
16
net/modemmanager/files/25-modemmanager-tty
Normal file
16
net/modemmanager/files/25-modemmanager-tty
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (C) 2016 Velocloud Inc
|
||||||
|
# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
|
||||||
|
# Load hotplug common utilities
|
||||||
|
. /usr/share/ModemManager/modemmanager.common
|
||||||
|
|
||||||
|
# We require a device name
|
||||||
|
[ -n "$DEVNAME" ] || exit
|
||||||
|
|
||||||
|
# Always make sure the rundir exists
|
||||||
|
mkdir -m 0755 -p "${MODEMMANAGER_RUNDIR}"
|
||||||
|
|
||||||
|
# Report TTY
|
||||||
|
mm_log "${ACTION} serial interface ${DEVNAME}: event processed"
|
||||||
|
mm_report_event "${ACTION}" "${DEVNAME}" "tty" "/sys${DEVPATH}"
|
13
net/modemmanager/files/25-modemmanager-usb
Normal file
13
net/modemmanager/files/25-modemmanager-usb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
|
||||||
|
# We need to process only full USB device removal events, we don't
|
||||||
|
# want to process specific interface removal events.
|
||||||
|
[ "$ACTION" = remove ] || exit
|
||||||
|
[ -z "${INTERFACE}" ] || exit
|
||||||
|
|
||||||
|
# Load common utilities
|
||||||
|
. /usr/share/ModemManager/modemmanager.common
|
||||||
|
|
||||||
|
mm_clear_modem_wait_status "/sys${DEVPATH}"
|
||||||
|
mm_cleanup_interface_by_sysfspath "/sys${DEVPATH}"
|
332
net/modemmanager/files/modemmanager.common
Normal file
332
net/modemmanager/files/modemmanager.common
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (C) 2016 Velocloud Inc
|
||||||
|
# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
. /lib/netifd/netifd-proto.sh
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Runtime state
|
||||||
|
|
||||||
|
MODEMMANAGER_RUNDIR="/var/run/modemmanager"
|
||||||
|
MODEMMANAGER_PID_FILE="${MODEMMANAGER_RUNDIR}/modemmanager.pid"
|
||||||
|
MODEMMANAGER_CDCWDM_CACHE="${MODEMMANAGER_RUNDIR}/cdcwdm.cache"
|
||||||
|
MODEMMANAGER_SYSFS_CACHE="${MODEMMANAGER_RUNDIR}/sysfs.cache"
|
||||||
|
MODEMMANAGER_EVENTS_CACHE="${MODEMMANAGER_RUNDIR}/events.cache"
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Common logging
|
||||||
|
|
||||||
|
mm_log() {
|
||||||
|
logger -t "ModemManager" "hotplug: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Receives as input argument the full sysfs path of the device
|
||||||
|
# Returns the physical device sysfs path
|
||||||
|
#
|
||||||
|
# NOTE: this method only works when the device exists, i.e. it cannot be used
|
||||||
|
# on removal hotplug events
|
||||||
|
|
||||||
|
mm_find_physdev_sysfs_path() {
|
||||||
|
local tmp_path="$1"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
tmp_path=$(dirname "${tmp_path}")
|
||||||
|
|
||||||
|
# avoid infinite loops iterating
|
||||||
|
[ -z "${tmp_path}" ] || [ "${tmp_path}" = "/" ] && return
|
||||||
|
|
||||||
|
# the physical device will be that with a idVendor and idProduct pair of files
|
||||||
|
[ -f "${tmp_path}"/idVendor ] && [ -f "${tmp_path}"/idProduct ] && {
|
||||||
|
tmp_path=$(readlink -f "$tmp_path")
|
||||||
|
echo "${tmp_path}"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Returns the cdc-wdm name retrieved from sysfs
|
||||||
|
mm_track_cdcwdm() {
|
||||||
|
local wwan="$1"
|
||||||
|
local cdcwdm
|
||||||
|
|
||||||
|
cdcwdm=$(ls "/sys/class/net/${wwan}/device/usbmisc/")
|
||||||
|
[ -n "${cdcwdm}" ] || return
|
||||||
|
|
||||||
|
# We have to cache it for later, as we won't be able to get the
|
||||||
|
# associated cdc-wdm device on a remove event
|
||||||
|
echo "${wwan} ${cdcwdm}" >> "${MODEMMANAGER_CDCWDM_CACHE}"
|
||||||
|
|
||||||
|
echo "${cdcwdm}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the cdc-wdm name retrieved from the cache
|
||||||
|
mm_untrack_cdcwdm() {
|
||||||
|
local wwan="$1"
|
||||||
|
local cdcwdm
|
||||||
|
|
||||||
|
# Look for the cached associated cdc-wdm device
|
||||||
|
[ -f "${MODEMMANAGER_CDCWDM_CACHE}" ] || return
|
||||||
|
|
||||||
|
cdcwdm=$(awk -v wwan="${wwan}" '!/^#/ && $0 ~ wwan { print $2 }' "${MODEMMANAGER_CDCWDM_CACHE}")
|
||||||
|
[ -n "${cdcwdm}" ] || return
|
||||||
|
|
||||||
|
# Remove from cache
|
||||||
|
sed -i "/${wwan} ${cdcwdm}/d" "${MODEMMANAGER_CDCWDM_CACHE}"
|
||||||
|
|
||||||
|
echo "${cdcwdm}"
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# ModemManager needs some time from the ports being added until a modem object
|
||||||
|
# is exposed in DBus. With the logic here we do an explicit wait of N seconds
|
||||||
|
# for ModemManager to expose the new modem object, making sure that the wait is
|
||||||
|
# unique per device (i.e. per physical device sysfs path).
|
||||||
|
|
||||||
|
# Gets the modem wait status as retrieved from the cache
|
||||||
|
mm_get_modem_wait_status() {
|
||||||
|
local sysfspath="$1"
|
||||||
|
|
||||||
|
# If no sysfs cache file, we're done
|
||||||
|
[ -f "${MODEMMANAGER_SYSFS_CACHE}" ] || return
|
||||||
|
|
||||||
|
# Get status of the sysfs path
|
||||||
|
awk -v sysfspath="${sysfspath}" '!/^#/ && $0 ~ sysfspath { print $2 }' "${MODEMMANAGER_SYSFS_CACHE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clear the modem wait status from the cache, if any
|
||||||
|
mm_clear_modem_wait_status() {
|
||||||
|
local sysfspath="$1"
|
||||||
|
|
||||||
|
local escaped_sysfspath
|
||||||
|
|
||||||
|
[ -f "${MODEMMANAGER_SYSFS_CACHE}" ] && {
|
||||||
|
# escape '/', '\' and '&' for sed...
|
||||||
|
escaped_sysfspath=$(echo "$sysfspath" | sed -e 's/[\/&]/\\&/g')
|
||||||
|
sed -i "/${escaped_sysfspath}/d" "${MODEMMANAGER_SYSFS_CACHE}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sets the modem wait status in the cache
|
||||||
|
mm_set_modem_wait_status() {
|
||||||
|
local sysfspath="$1"
|
||||||
|
local status="$2"
|
||||||
|
|
||||||
|
# Remove sysfs line before adding the new one with the new state
|
||||||
|
mm_clear_modem_wait_status "${sysfspath}"
|
||||||
|
|
||||||
|
# Add the new status
|
||||||
|
echo "${sysfspath} ${status}" >> "${MODEMMANAGER_SYSFS_CACHE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Callback for config_foreach()
|
||||||
|
mm_get_modem_config_foreach_cb() {
|
||||||
|
local cfg="$1"
|
||||||
|
local sysfspath="$2"
|
||||||
|
|
||||||
|
local proto
|
||||||
|
config_get proto "${cfg}" proto
|
||||||
|
[ "${proto}" = modemmanager ] || return 0
|
||||||
|
|
||||||
|
local dev
|
||||||
|
dev=$(uci_get network "${cfg}" device)
|
||||||
|
[ "${dev}" = "${sysfspath}" ] || return 0
|
||||||
|
|
||||||
|
echo "${cfg}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the name of the interface configured for this device
|
||||||
|
mm_get_modem_config() {
|
||||||
|
local sysfspath="$1"
|
||||||
|
|
||||||
|
# Look for configuration for the given sysfs path
|
||||||
|
config_load network
|
||||||
|
config_foreach mm_get_modem_config_foreach_cb interface "${sysfspath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for a modem in the specified sysfspath
|
||||||
|
mm_wait_for_modem() {
|
||||||
|
local cfg="$1"
|
||||||
|
local sysfspath="$2"
|
||||||
|
|
||||||
|
# TODO: config max wait
|
||||||
|
local n=45
|
||||||
|
local step=5
|
||||||
|
|
||||||
|
while [ $n -ge 0 ]; do
|
||||||
|
[ -d "${sysfspath}" ] || {
|
||||||
|
mm_log "error: ignoring modem detection request: no device at ${sysfspath}"
|
||||||
|
proto_set_available "${cfg}" 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the modem exists at the given sysfs path
|
||||||
|
if ! mmcli -m "${sysfspath}" > /dev/null 2>&1
|
||||||
|
then
|
||||||
|
mm_log "error: modem not detected at sysfs path"
|
||||||
|
else
|
||||||
|
mm_log "modem exported successfully at ${sysfspath}"
|
||||||
|
mm_log "setting interface '${cfg}' as available"
|
||||||
|
proto_set_available "${cfg}" 1
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep $step
|
||||||
|
n=$((n-step))
|
||||||
|
done
|
||||||
|
|
||||||
|
mm_log "error: timed out waiting for the modem to get exported at ${sysfspath}"
|
||||||
|
proto_set_available "${cfg}" 0
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_report_modem_wait() {
|
||||||
|
local sysfspath=$1
|
||||||
|
|
||||||
|
local parent_sysfspath status
|
||||||
|
|
||||||
|
parent_sysfspath=$(mm_find_physdev_sysfs_path "$sysfspath")
|
||||||
|
[ -n "${parent_sysfspath}" ] || {
|
||||||
|
mm_log "error: parent device sysfspath not found"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status=$(mm_get_modem_wait_status "${parent_sysfspath}")
|
||||||
|
case "${status}" in
|
||||||
|
"")
|
||||||
|
local cfg
|
||||||
|
|
||||||
|
cfg=$(mm_get_modem_config "${parent_sysfspath}")
|
||||||
|
if [ -n "${cfg}" ]; then
|
||||||
|
mm_log "interface '${cfg}' is set to configure device '${parent_sysfspath}'"
|
||||||
|
mm_log "now waiting for modem at sysfs path ${parent_sysfspath}"
|
||||||
|
mm_set_modem_wait_status "${parent_sysfspath}" "processed"
|
||||||
|
# Launch subshell for the explicit wait
|
||||||
|
( mm_wait_for_modem "${cfg}" "${parent_sysfspath}" ) > /dev/null 2>&1 &
|
||||||
|
else
|
||||||
|
mm_log "no need to wait for modem at sysfs path ${parent_sysfspath}"
|
||||||
|
mm_set_modem_wait_status "${parent_sysfspath}" "ignored"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"processed")
|
||||||
|
mm_log "already waiting for modem at sysfs path ${parent_sysfspath}"
|
||||||
|
;;
|
||||||
|
"ignored")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
mm_log "error: unknown status read for device at sysfs path ${parent_sysfspath}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Cleanup interfaces
|
||||||
|
|
||||||
|
mm_cleanup_interface_cb() {
|
||||||
|
local cfg="$1"
|
||||||
|
|
||||||
|
local proto
|
||||||
|
config_get proto "${cfg}" proto
|
||||||
|
[ "${proto}" = modemmanager ] || return 0
|
||||||
|
|
||||||
|
proto_set_available "${cfg}" 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_cleanup_interfaces() {
|
||||||
|
config_load network
|
||||||
|
config_foreach mm_cleanup_interface_cb interface
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_cleanup_interface_by_sysfspath() {
|
||||||
|
local dev="$1"
|
||||||
|
|
||||||
|
local cfg
|
||||||
|
cfg=$(mm_get_modem_config "$dev")
|
||||||
|
[ -n "${cfg}" ] || return
|
||||||
|
|
||||||
|
mm_log "setting interface '$cfg' as unavailable"
|
||||||
|
proto_set_available "${cfg}" 0
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Event reporting
|
||||||
|
|
||||||
|
# Receives as input the action, the device name and the subsystem
|
||||||
|
mm_report_event() {
|
||||||
|
local action="$1"
|
||||||
|
local name="$2"
|
||||||
|
local subsystem="$3"
|
||||||
|
local sysfspath="$4"
|
||||||
|
|
||||||
|
# Track/untrack events in cache
|
||||||
|
case "${action}" in
|
||||||
|
"add")
|
||||||
|
# On add events, store event details in cache (if not exists yet)
|
||||||
|
grep -qs "${name},${subsystem}" "${MODEMMANAGER_EVENTS_CACHE}" || \
|
||||||
|
echo "${action},${name},${subsystem},${sysfspath}" >> "${MODEMMANAGER_EVENTS_CACHE}"
|
||||||
|
;;
|
||||||
|
"remove")
|
||||||
|
# On remove events, remove old events from cache (match by subsystem+name)
|
||||||
|
sed -i "/${name},${subsystem}/d" "${MODEMMANAGER_EVENTS_CACHE}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Report the event
|
||||||
|
mm_log "event reported: action=${action}, name=${name}, subsystem=${subsystem}"
|
||||||
|
mmcli --report-kernel-event="action=${action},name=${name},subsystem=${subsystem}" 1>/dev/null 2>&1 &
|
||||||
|
|
||||||
|
# Wait for added modem if a sysfspath is given
|
||||||
|
[ -n "${sysfspath}" ] && [ "$action" = "add" ] && mm_report_modem_wait "${sysfspath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_report_event_from_cache_line() {
|
||||||
|
local event_line="$1"
|
||||||
|
|
||||||
|
local action name subsystem sysfspath
|
||||||
|
action=$(echo "${event_line}" | awk -F ',' '{ print $1 }')
|
||||||
|
name=$(echo "${event_line}" | awk -F ',' '{ print $2 }')
|
||||||
|
subsystem=$(echo "${event_line}" | awk -F ',' '{ print $3 }')
|
||||||
|
sysfspath=$(echo "${event_line}" | awk -F ',' '{ print $4 }')
|
||||||
|
|
||||||
|
mm_log "cached event found: action=${action}, name=${name}, subsystem=${subsystem}, sysfspath=${sysfspath}"
|
||||||
|
mm_report_event "${action}" "${name}" "${subsystem}" "${sysfspath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_report_events_from_cache() {
|
||||||
|
# Remove the sysfs cache
|
||||||
|
rm -f "${MODEMMANAGER_SYSFS_CACHE}"
|
||||||
|
|
||||||
|
local n=10
|
||||||
|
local step=1
|
||||||
|
local mmrunning=0
|
||||||
|
|
||||||
|
# Wait for ModemManager to be available in the bus
|
||||||
|
while [ $n -ge 0 ]; do
|
||||||
|
sleep $step
|
||||||
|
mm_log "checking if ModemManager is available..."
|
||||||
|
|
||||||
|
if ! mmcli -L >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
mm_log "ModemManager not yet available"
|
||||||
|
else
|
||||||
|
mmrunning=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
n=$((n-step))
|
||||||
|
done
|
||||||
|
|
||||||
|
[ ${mmrunning} -eq 1 ] || {
|
||||||
|
mm_log "error: couldn't report initial kernel events: ModemManager not running"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Report cached kernel events
|
||||||
|
while IFS= read -r event_line; do
|
||||||
|
mm_report_event_from_cache_line "${event_line}"
|
||||||
|
done < ${MODEMMANAGER_EVENTS_CACHE}
|
||||||
|
}
|
33
net/modemmanager/files/modemmanager.init
Executable file
33
net/modemmanager/files/modemmanager.init
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
START=70
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
# Load common utils
|
||||||
|
. /usr/share/ModemManager/modemmanager.common
|
||||||
|
# Set all configured interfaces as unavailable
|
||||||
|
mm_cleanup_interfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
# Load common utils
|
||||||
|
. /usr/share/ModemManager/modemmanager.common
|
||||||
|
|
||||||
|
# Always make sure the rundir exists
|
||||||
|
mkdir -m 0755 -p "${MODEMMANAGER_RUNDIR}"
|
||||||
|
|
||||||
|
# Initially set all configured interfaces as unavailable
|
||||||
|
mm_cleanup_interfaces
|
||||||
|
|
||||||
|
# Report cached events (will wait for MM to be launched)
|
||||||
|
( mm_report_events_from_cache ) >/dev/null 2>&1 &
|
||||||
|
|
||||||
|
# Setup ModemManager service
|
||||||
|
procd_open_instance
|
||||||
|
procd_set_param command /usr/sbin/ModemManager
|
||||||
|
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
|
||||||
|
procd_set_param pidfile "${MODEMMANAGER_PID_FILE}"
|
||||||
|
procd_close_instance
|
||||||
|
}
|
501
net/modemmanager/files/modemmanager.proto
Executable file
501
net/modemmanager/files/modemmanager.proto
Executable file
@ -0,0 +1,501 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright (C) 2016-2019 Aleksander Morgado <aleksander@aleksander.es>
|
||||||
|
|
||||||
|
[ -x /usr/bin/mmcli ] || exit 0
|
||||||
|
[ -x /usr/sbin/pppd ] || exit 0
|
||||||
|
|
||||||
|
[ -n "$INCLUDE_ONLY" ] || {
|
||||||
|
. /lib/functions.sh
|
||||||
|
. ../netifd-proto.sh
|
||||||
|
. ./ppp.sh
|
||||||
|
init_proto "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
cdr2mask ()
|
||||||
|
{
|
||||||
|
# Number of args to shift, 255..255, first non-255 byte, zeroes
|
||||||
|
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
|
||||||
|
if [ "$1" -gt 1 ]
|
||||||
|
then
|
||||||
|
shift "$1"
|
||||||
|
else
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
echo "${1-0}"."${2-0}"."${3-0}"."${4-0}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# This method expects as first argument a list of key-value pairs, as returned by mmcli --output-keyvalue
|
||||||
|
# The second argument must be exactly the name of the field to read
|
||||||
|
#
|
||||||
|
# Sample output:
|
||||||
|
# $ mmcli -m 0 -K
|
||||||
|
# modem.dbus-path : /org/freedesktop/ModemManager1/Modem/0
|
||||||
|
# modem.generic.device-identifier : ed6eff2e3e0f90463da1c2a755b2acacd1335752
|
||||||
|
# modem.generic.manufacturer : Dell Inc.
|
||||||
|
# modem.generic.model : DW5821e Snapdragon X20 LTE
|
||||||
|
# modem.generic.revision : T77W968.F1.0.0.4.0.GC.009\n026
|
||||||
|
# modem.generic.carrier-configuration : GCF
|
||||||
|
# modem.generic.carrier-configuration-revision : 08E00009
|
||||||
|
# modem.generic.hardware-revision : DW5821e Snapdragon X20 LTE
|
||||||
|
# ....
|
||||||
|
modemmanager_get_field() {
|
||||||
|
local list=$1
|
||||||
|
local field=$2
|
||||||
|
local value=""
|
||||||
|
|
||||||
|
[ -z "${list}" ] || [ -z "${field}" ] && return
|
||||||
|
|
||||||
|
# there is always at least a whitespace after each key, and we use that as part of the
|
||||||
|
# key matching we do (e.g. to avoid getting 'modem.generic.state-failed-reason' as a result
|
||||||
|
# when grepping for 'modem.generic.state'.
|
||||||
|
line=$(echo "${list}" | grep "${field} ")
|
||||||
|
value=$(echo ${line#*:})
|
||||||
|
|
||||||
|
# not found?
|
||||||
|
[ -n "${value}" ] || return 2
|
||||||
|
|
||||||
|
# only print value if set
|
||||||
|
[ "${value}" != "--" ] && echo "${value}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# build a comma-separated list of values from the list
|
||||||
|
modemmanager_get_multivalue_field() {
|
||||||
|
local list=$1
|
||||||
|
local field=$2
|
||||||
|
local value=""
|
||||||
|
local length idx item
|
||||||
|
|
||||||
|
[ -z "${list}" ] || [ -z "${field}" ] && return
|
||||||
|
|
||||||
|
length=$(modemmanager_get_field "${list}" "${field}.length")
|
||||||
|
[ -n "${length}" ] || return 0
|
||||||
|
[ "$length" -ge 1 ] || return 0
|
||||||
|
|
||||||
|
idx=1
|
||||||
|
while [ $idx -le "$length" ]; do
|
||||||
|
item=$(modemmanager_get_field "${list}" "${field}.value\[$idx\]")
|
||||||
|
[ -n "${item}" ] && [ "${item}" != "--" ] && {
|
||||||
|
[ -n "${value}" ] && value="${value}, "
|
||||||
|
value="${value}${item}"
|
||||||
|
}
|
||||||
|
idx=$((idx + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
# nothing built?
|
||||||
|
[ -n "${value}" ] || return 2
|
||||||
|
|
||||||
|
# only print value if set
|
||||||
|
echo "${value}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_cleanup_connection() {
|
||||||
|
local modemstatus="$1"
|
||||||
|
|
||||||
|
local bearercount idx bearerpath
|
||||||
|
|
||||||
|
bearercount=$(modemmanager_get_field "${modemstatus}" "modem.generic.bearers.length")
|
||||||
|
|
||||||
|
# do nothing if no bearers reported
|
||||||
|
[ -n "${bearercount}" ] && [ "$bearercount" -ge 1 ] && {
|
||||||
|
# explicitly disconnect just in case
|
||||||
|
mmcli --modem="${device}" --simple-disconnect >/dev/null 2>&1
|
||||||
|
# and remove all bearer objects, if any found
|
||||||
|
idx=1
|
||||||
|
while [ $idx -le "$bearercount" ]; do
|
||||||
|
bearerpath=$(modemmanager_get_field "${modemstatus}" "modem.generic.bearers.value\[$idx\]")
|
||||||
|
mmcli --modem "${device}" --delete-bearer="${bearerpath}" >/dev/null 2>&1
|
||||||
|
idx=$((idx + 1))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_connected_method_ppp_ipv4() {
|
||||||
|
local interface="$1"
|
||||||
|
local ttyname="$2"
|
||||||
|
local username="$3"
|
||||||
|
local password="$4"
|
||||||
|
|
||||||
|
proto_run_command "${interface}" /usr/sbin/pppd \
|
||||||
|
"${ttyname}" \
|
||||||
|
115200 \
|
||||||
|
nodetach \
|
||||||
|
noaccomp \
|
||||||
|
nobsdcomp \
|
||||||
|
nopcomp \
|
||||||
|
novj \
|
||||||
|
noauth \
|
||||||
|
${username:+ user $username} \
|
||||||
|
${password:+ password $password} \
|
||||||
|
lcp-echo-failure 5 \
|
||||||
|
lcp-echo-interval 15 \
|
||||||
|
lock \
|
||||||
|
crtscts \
|
||||||
|
nodefaultroute \
|
||||||
|
usepeerdns \
|
||||||
|
ipparam "${interface}" \
|
||||||
|
ip-up-script /lib/netifd/ppp-up \
|
||||||
|
ip-down-script /lib/netifd/ppp-down
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_disconnected_method_ppp_ipv4() {
|
||||||
|
local interface="$1"
|
||||||
|
|
||||||
|
echo "running disconnection (ppp method)"
|
||||||
|
|
||||||
|
[ -n "${ERROR}" ] && {
|
||||||
|
local errorstring
|
||||||
|
errorstring=$(ppp_exitcode_tostring "${ERROR}")
|
||||||
|
case "$ERROR" in
|
||||||
|
0)
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
proto_notify_error "$interface" "$errorstring"
|
||||||
|
proto_block_restart "$interface"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
proto_notify_error "$interface" "$errorstring"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
} || echo "pppd result code not given"
|
||||||
|
|
||||||
|
proto_kill_command "$interface"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_connected_method_dhcp_ipv4() {
|
||||||
|
local interface="$1"
|
||||||
|
local wwan="$2"
|
||||||
|
local metric="$3"
|
||||||
|
|
||||||
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_string name "${interface}_4"
|
||||||
|
json_add_string ifname "@${interface}"
|
||||||
|
json_add_string proto "dhcp"
|
||||||
|
proto_add_dynamic_defaults
|
||||||
|
[ -n "$metric" ] && json_add_int metric "${metric}"
|
||||||
|
json_close_object
|
||||||
|
ubus call network add_dynamic "$(json_dump)"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_connected_method_static_ipv4() {
|
||||||
|
local interface="$1"
|
||||||
|
local wwan="$2"
|
||||||
|
local address="$3"
|
||||||
|
local prefix="$4"
|
||||||
|
local gateway="$5"
|
||||||
|
local mtu="$6"
|
||||||
|
local dns1="$7"
|
||||||
|
local dns2="$8"
|
||||||
|
local metric="$9"
|
||||||
|
|
||||||
|
local mask=""
|
||||||
|
|
||||||
|
[ -n "${address}" ] || {
|
||||||
|
proto_notify_error "${interface}" ADDRESS_MISSING
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "${prefix}" ] || {
|
||||||
|
proto_notify_error "${interface}" PREFIX_MISSING
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mask=$(cdr2mask "${prefix}")
|
||||||
|
|
||||||
|
# TODO: mtu reporting in proto handler
|
||||||
|
|
||||||
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
|
echo "adding IPv4 address ${address}, netmask ${mask}"
|
||||||
|
proto_add_ipv4_address "${address}" "${mask}"
|
||||||
|
[ -n "${gateway}" ] && {
|
||||||
|
echo "adding default IPv4 route via ${gateway}"
|
||||||
|
proto_add_ipv4_route "0.0.0.0" "0" "${gateway}" "${address}"
|
||||||
|
}
|
||||||
|
[ -n "${dns1}" ] && {
|
||||||
|
echo "adding primary DNS at ${dns1}"
|
||||||
|
proto_add_dns_server "${dns1}"
|
||||||
|
}
|
||||||
|
[ -n "${dns2}" ] && {
|
||||||
|
echo "adding secondary DNS at ${dns2}"
|
||||||
|
proto_add_dns_server "${dns2}"
|
||||||
|
}
|
||||||
|
[ -n "$metric" ] && json_add_int metric "${metric}"
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_connected_method_dhcp_ipv6() {
|
||||||
|
local interface="$1"
|
||||||
|
local wwan="$2"
|
||||||
|
local metric="$3"
|
||||||
|
|
||||||
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_string name "${interface}_6"
|
||||||
|
json_add_string ifname "@${interface}"
|
||||||
|
json_add_string proto "dhcpv6"
|
||||||
|
proto_add_dynamic_defaults
|
||||||
|
json_add_string extendprefix 1 # RFC 7278: Extend an IPv6 /64 Prefix to LAN
|
||||||
|
[ -n "$metric" ] && json_add_int metric "${metric}"
|
||||||
|
json_close_object
|
||||||
|
ubus call network add_dynamic "$(json_dump)"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_connected_method_static_ipv6() {
|
||||||
|
local interface="$1"
|
||||||
|
local wwan="$2"
|
||||||
|
local address="$3"
|
||||||
|
local prefix="$4"
|
||||||
|
local gateway="$5"
|
||||||
|
local mtu="$6"
|
||||||
|
local dns1="$7"
|
||||||
|
local dns2="$8"
|
||||||
|
local metric="$9"
|
||||||
|
|
||||||
|
[ -n "${address}" ] || {
|
||||||
|
proto_notify_error "${interface}" ADDRESS_MISSING
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "${prefix}" ] || {
|
||||||
|
proto_notify_error "${interface}" PREFIX_MISSING
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: mtu reporting in proto handler
|
||||||
|
|
||||||
|
proto_init_update "${wwan}" 1
|
||||||
|
proto_set_keep 1
|
||||||
|
echo "adding IPv6 address ${address}, prefix ${prefix}"
|
||||||
|
proto_add_ipv6_address "${address}" "128"
|
||||||
|
proto_add_ipv6_prefix "${address}/${prefix}"
|
||||||
|
[ -n "${gateway}" ] && {
|
||||||
|
echo "adding default IPv6 route via ${gateway}"
|
||||||
|
proto_add_ipv6_route "${gateway}" "128"
|
||||||
|
proto_add_ipv6_route "::0" "0" "${gateway}" "" "" "${address}/${prefix}"
|
||||||
|
}
|
||||||
|
[ -n "${dns1}" ] && {
|
||||||
|
echo "adding primary DNS at ${dns1}"
|
||||||
|
proto_add_dns_server "${dns1}"
|
||||||
|
}
|
||||||
|
[ -n "${dns2}" ] && {
|
||||||
|
echo "adding secondary DNS at ${dns2}"
|
||||||
|
proto_add_dns_server "${dns2}"
|
||||||
|
}
|
||||||
|
[ -n "$metric" ] && json_add_int metric "${metric}"
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
}
|
||||||
|
|
||||||
|
modemmanager_disconnected_method_common() {
|
||||||
|
local interface="$1"
|
||||||
|
|
||||||
|
echo "running disconnection (common)"
|
||||||
|
|
||||||
|
proto_init_update "*" 0
|
||||||
|
proto_send_update "${interface}"
|
||||||
|
}
|
||||||
|
|
||||||
|
proto_modemmanager_init_config() {
|
||||||
|
available=1
|
||||||
|
no_device=1
|
||||||
|
proto_config_add_string device
|
||||||
|
proto_config_add_string apn
|
||||||
|
proto_config_add_string username
|
||||||
|
proto_config_add_string password
|
||||||
|
proto_config_add_string pincode
|
||||||
|
proto_config_add_string iptype
|
||||||
|
proto_config_add_boolean lowpower
|
||||||
|
proto_config_add_defaults
|
||||||
|
}
|
||||||
|
|
||||||
|
proto_modemmanager_setup() {
|
||||||
|
local interface="$1"
|
||||||
|
|
||||||
|
local modempath modemstatus bearercount bearerpath connectargs bearerstatus beareriface
|
||||||
|
local bearermethod_ipv4 bearermethod_ipv6
|
||||||
|
local operatorname operatorid registration accesstech signalquality
|
||||||
|
|
||||||
|
local device apn username password pincode iptype metric
|
||||||
|
|
||||||
|
local address prefix gateway mtu dns1 dns2
|
||||||
|
|
||||||
|
json_get_vars device apn username password pincode iptype metric
|
||||||
|
|
||||||
|
# validate sysfs path given in config
|
||||||
|
[ -n "${device}" ] || {
|
||||||
|
echo "No device specified"
|
||||||
|
proto_notify_error "${interface}" NO_DEVICE
|
||||||
|
proto_set_available "${interface}" 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
[ -e "${device}" ] || {
|
||||||
|
echo "Device not found in sysfs"
|
||||||
|
proto_set_available "${interface}" 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# validate that ModemManager is handling the modem at the sysfs path
|
||||||
|
modemstatus=$(mmcli --modem="${device}" --output-keyvalue)
|
||||||
|
modempath=$(modemmanager_get_field "${modemstatus}" "modem.dbus-path")
|
||||||
|
[ -n "${modempath}" ] || {
|
||||||
|
echo "Device not managed by ModemManager"
|
||||||
|
proto_notify_error "${interface}" DEVICE_NOT_MANAGED
|
||||||
|
proto_set_available "${interface}" 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
echo "modem available at ${modempath}"
|
||||||
|
|
||||||
|
# always cleanup before attempting a new connection, just in case
|
||||||
|
modemmanager_cleanup_connection "${modemstatus}"
|
||||||
|
|
||||||
|
# setup connect args; APN mandatory (even if it may be empty)
|
||||||
|
echo "starting connection with apn '${apn}'..."
|
||||||
|
connectargs="apn=${apn}${iptype:+,ip-type=${iptype}}${username:+,user=${username}}${password:+,password=${password}}${pincode:+,pin=${pincode}}"
|
||||||
|
mmcli --modem="${device}" --timeout 120 --simple-connect="${connectargs}" || {
|
||||||
|
proto_notify_error "${interface}" CONNECT_FAILED
|
||||||
|
proto_block_restart "${interface}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# log additional useful information
|
||||||
|
modemstatus=$(mmcli --modem="${device}" --output-keyvalue)
|
||||||
|
operatorname=$(modemmanager_get_field "${modemstatus}" "modem.3gpp.operator-name")
|
||||||
|
[ -n "${operatorname}" ] && echo "network operator name: ${operatorname}"
|
||||||
|
operatorid=$(modemmanager_get_field "${modemstatus}" "modem.3gpp.operator-code")
|
||||||
|
[ -n "${operatorid}" ] && echo "network operator MCCMNC: ${operatorid}"
|
||||||
|
registration=$(modemmanager_get_field "${modemstatus}" "modem.3gpp.registration-state")
|
||||||
|
[ -n "${registration}" ] && echo "registration type: ${registration}"
|
||||||
|
accesstech=$(modemmanager_get_multivalue_field "${modemstatus}" "modem.generic.access-technologies")
|
||||||
|
[ -n "${accesstech}" ] && echo "access technology: ${accesstech}"
|
||||||
|
signalquality=$(modemmanager_get_field "${modemstatus}" "modem.generic.signal-quality.value")
|
||||||
|
[ -n "${signalquality}" ] && echo "signal quality: ${signalquality}%"
|
||||||
|
|
||||||
|
# we won't like it if there are more than one bearers, as that would mean the
|
||||||
|
# user manually created them, and that's unsupported by this proto
|
||||||
|
bearercount=$(modemmanager_get_field "${modemstatus}" "modem.generic.bearers.length")
|
||||||
|
[ -n "${bearercount}" ] && [ "$bearercount" -eq 1 ] || {
|
||||||
|
proto_notify_error "${interface}" INVALID_BEARER_LIST
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# load connected bearer information
|
||||||
|
bearerpath=$(modemmanager_get_field "${modemstatus}" "modem.generic.bearers.value\[1\]")
|
||||||
|
bearerstatus=$(mmcli --bearer "${bearerpath}" --output-keyvalue)
|
||||||
|
|
||||||
|
# load network interface and method information
|
||||||
|
beareriface=$(modemmanager_get_field "${bearerstatus}" "bearer.status.interface")
|
||||||
|
bearermethod_ipv4=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
|
||||||
|
bearermethod_ipv6=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.method")
|
||||||
|
|
||||||
|
# setup IPv4
|
||||||
|
[ -n "${bearermethod_ipv4}" ] && {
|
||||||
|
echo "IPv4 connection setup required in interface ${interface}: ${bearermethod_ipv4}"
|
||||||
|
case "${bearermethod_ipv4}" in
|
||||||
|
"dhcp")
|
||||||
|
modemmanager_connected_method_dhcp_ipv4 "${interface}" "${beareriface}" "${metric}"
|
||||||
|
;;
|
||||||
|
"static")
|
||||||
|
address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.address")
|
||||||
|
prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.prefix")
|
||||||
|
gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.gateway")
|
||||||
|
mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.mtu")
|
||||||
|
dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[1\]")
|
||||||
|
dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.dns.value\[2\]")
|
||||||
|
modemmanager_connected_method_static_ipv4 "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
|
||||||
|
;;
|
||||||
|
"ppp")
|
||||||
|
modemmanager_connected_method_ppp_ipv4 "${interface}" "${beareriface}" "${username}" "${password}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
proto_notify_error "${interface}" UNKNOWN_METHOD
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# setup IPv6
|
||||||
|
# note: if using ipv4v6, both IPv4 and IPv6 settings will have the same MTU and metric values reported
|
||||||
|
[ -n "${bearermethod_ipv6}" ] && {
|
||||||
|
echo "IPv6 connection setup required in interface ${interface}: ${bearermethod_ipv6}"
|
||||||
|
case "${bearermethod_ipv6}" in
|
||||||
|
"dhcp")
|
||||||
|
modemmanager_connected_method_dhcp_ipv6 "${interface}" "${beareriface}" "${metric}"
|
||||||
|
;;
|
||||||
|
"static")
|
||||||
|
address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.address")
|
||||||
|
prefix=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.prefix")
|
||||||
|
gateway=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.gateway")
|
||||||
|
mtu=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.mtu")
|
||||||
|
dns1=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.dns.value\[1\]")
|
||||||
|
dns2=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.dns.value\[2\]")
|
||||||
|
modemmanager_connected_method_static_ipv6 "${interface}" "${beareriface}" "${address}" "${prefix}" "${gateway}" "${mtu}" "${dns1}" "${dns2}" "${metric}"
|
||||||
|
;;
|
||||||
|
"ppp")
|
||||||
|
proto_notify_error "${interface}" "unsupported method"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
proto_notify_error "${interface}" UNKNOWN_METHOD
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
proto_modemmanager_teardown() {
|
||||||
|
local interface="$1"
|
||||||
|
|
||||||
|
local modemstatus bearerpath errorstring
|
||||||
|
local bearermethod_ipv4 bearermethod_ipv6
|
||||||
|
|
||||||
|
local device lowpower iptype
|
||||||
|
json_get_vars device lowpower iptype
|
||||||
|
|
||||||
|
echo "stopping network"
|
||||||
|
|
||||||
|
# load connected bearer information, just the first one should be ok
|
||||||
|
modemstatus=$(mmcli --modem="${device}" --output-keyvalue)
|
||||||
|
bearerpath=$(modemmanager_get_field "${modemstatus}" "modem.generic.bearers.value\[1\]")
|
||||||
|
[ -n "${bearerpath}" ] || {
|
||||||
|
echo "couldn't load bearer path"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# load bearer connection methods
|
||||||
|
bearerstatus=$(mmcli --bearer "${bearerpath}" --output-keyvalue)
|
||||||
|
bearermethod_ipv4=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.method")
|
||||||
|
[ -n "${bearermethod_ipv4}" ] &&
|
||||||
|
echo "IPv4 connection teardown required in interface ${interface}: ${bearermethod_ipv4}"
|
||||||
|
bearermethod_ipv6=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.method")
|
||||||
|
[ -n "${bearermethod_ipv6}" ] &&
|
||||||
|
echo "IPv6 connection teardown required in interface ${interface}: ${bearermethod_ipv6}"
|
||||||
|
|
||||||
|
# disconnection handling only requires special treatment in IPv4/PPP
|
||||||
|
[ "${bearermethod_ipv4}" = "ppp" ] && modemmanager_disconnected_method_ppp_ipv4 "${interface}"
|
||||||
|
modemmanager_disconnected_method_common "${interface}"
|
||||||
|
|
||||||
|
# disconnect
|
||||||
|
mmcli --modem="${device}" --simple-disconnect ||
|
||||||
|
proto_notify_error "${interface}" DISCONNECT_FAILED
|
||||||
|
|
||||||
|
# disable
|
||||||
|
mmcli --modem="${device}" --disable
|
||||||
|
|
||||||
|
# low power, only if requested
|
||||||
|
[ "${lowpower:-0}" -lt 1 ] ||
|
||||||
|
mmcli --modem="${device}" --set-power-state-low
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$INCLUDE_ONLY" ] || {
|
||||||
|
add_protocol modemmanager
|
||||||
|
}
|
75
net/nextdns/Makefile
Normal file
75
net/nextdns/Makefile
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2019 NextDNS Inc
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=nextdns
|
||||||
|
PKG_VERSION:=1.1.5
|
||||||
|
PKG_RELEASE:=3
|
||||||
|
|
||||||
|
PKG_SOURCE_PROTO:=git
|
||||||
|
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
|
||||||
|
PKG_SOURCE_URL:=https://github.com/nextdns/nextdns.git
|
||||||
|
PKG_MIRROR_HASH:=01ff61771bcf076f1659167b8676234fdefefac9cd0a05aa1d491a7c5f0145fa
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Olivier Poitrey <rs@nextdns.io>
|
||||||
|
PKG_LICENSE:=MIT
|
||||||
|
PKG_LICENSE_FILES:=LICENSE
|
||||||
|
|
||||||
|
PKG_BUILD_DEPENDS:=golang/host
|
||||||
|
PKG_BUILD_PARALLEL:=1
|
||||||
|
PKG_USE_MIPS16:=0
|
||||||
|
|
||||||
|
GO_PKG:=github.com/nextdns/nextdns
|
||||||
|
GO_PKG_LDFLAGS:=-s -w
|
||||||
|
GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION)
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
include ../../lang/golang/golang-package.mk
|
||||||
|
|
||||||
|
define Package/nextdns
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
TITLE:=NextDNS DNS over HTTPS Proxy
|
||||||
|
URL:=https://github.com/nextdns/nextdns
|
||||||
|
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/nextdns/install
|
||||||
|
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nextdns $(1)/usr/sbin/
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/nextdns.init $(1)/etc/init.d/nextdns
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_CONF) ./files/nextdns.config $(1)/etc/config/nextdns
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/nextdns/description
|
||||||
|
Official NextDNS DNS over HTTPS Proxy.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/golang-github-nextdns-nextdns-dev
|
||||||
|
$(call Package/nextdns)
|
||||||
|
$(call GoPackage/GoSubMenu)
|
||||||
|
TITLE+= (source files)
|
||||||
|
PKGARCH:=all
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/golang-github-nextdns-nextdns-dev/description
|
||||||
|
$(call Package/nextdns/description)
|
||||||
|
|
||||||
|
This package provides the source files for the client/bridge program.
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call GoBinPackage,nextdns))
|
||||||
|
$(eval $(call BuildPackage,nextdns))
|
||||||
|
$(eval $(call GoSrcPackage,golang-github-nextdns-nextdns-dev))
|
||||||
|
$(eval $(call BuildPackage,golang-github-nextdns-nextdns-dev))
|
31
net/nextdns/files/nextdns.config
Normal file
31
net/nextdns/files/nextdns.config
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
config nextdns main
|
||||||
|
option enabled '1'
|
||||||
|
|
||||||
|
# NextDNS custom configuration id (create on on https://nextdns.io).
|
||||||
|
# If not defined, this package will act as a non-logging, non-filtering
|
||||||
|
# DNS over HTTPS resolver.
|
||||||
|
#
|
||||||
|
#option config abcdef
|
||||||
|
|
||||||
|
# Custom configurations can also be conditionally assigned to LAN hosts based
|
||||||
|
# their MAC address or subnet. The first matching host_config wins. If both
|
||||||
|
# host_config and config are defined, config is always placed last, as default
|
||||||
|
# option.
|
||||||
|
#
|
||||||
|
#list host_config 'da:c8:6d:b6:93:78=fedcba'
|
||||||
|
#list host_config '10.0.1.2/32=abc123'
|
||||||
|
#list host_config '10.0.3.0/24=def321'
|
||||||
|
|
||||||
|
# Listen on a custom local port so a DNS front (like dnsmasq) can use us as
|
||||||
|
# a forwarder.
|
||||||
|
option listen '127.0.0.1:5342'
|
||||||
|
|
||||||
|
# Expose LAN clients information in NextDNS analytics.
|
||||||
|
option report_client_info '1'
|
||||||
|
|
||||||
|
# When enabled, use DNS servers located in jurisdictions with strong privacy laws.
|
||||||
|
# Available locations are: Switzerland, Iceland, Finland, Panama and Hong Kong.
|
||||||
|
option hardened_privacy '0'
|
||||||
|
|
||||||
|
# Log individual queries to system log.
|
||||||
|
option log_queries '0'
|
76
net/nextdns/files/nextdns.init
Normal file
76
net/nextdns/files/nextdns.init
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
# shellcheck disable=SC2034 disable=SC2154
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
# starts after network starts
|
||||||
|
START=21
|
||||||
|
# stops before networking stops
|
||||||
|
STOP=89
|
||||||
|
|
||||||
|
PROG=/usr/sbin/nextdns
|
||||||
|
|
||||||
|
add_dnsmasq_opt() {
|
||||||
|
mkdir -p /tmp/dnsmasq.d
|
||||||
|
echo "$1" >> /tmp/dnsmasq.d/nextdns.conf
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsmasq_reload() {
|
||||||
|
# Reload dnsmasq is already running.
|
||||||
|
if /etc/init.d/dnsmasq running; then
|
||||||
|
/etc/init.d/dnsmasq reload
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_host_config() {
|
||||||
|
host_config_args="$host_config_args -config=$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
config_load nextdns
|
||||||
|
config_get_bool enabled main enabled "1"
|
||||||
|
rm -f /tmp/dnsmasq.d/nextdns.conf
|
||||||
|
if [ "$enabled" = "1" ]; then
|
||||||
|
config_get config main config ""
|
||||||
|
config_list_foreach main host_config handle_host_config
|
||||||
|
config_get listen main listen "127.0.0.1:5342"
|
||||||
|
config_get_bool report_client_info main report_client_info "1"
|
||||||
|
config_get_bool hardened_privacy main hardened_privacy "0"
|
||||||
|
config_get_bool log_queries main log_queries "0"
|
||||||
|
|
||||||
|
# Add a custom configuration for dnsmasq.
|
||||||
|
server=$(echo "$listen" | sed -e 's/:/#/')
|
||||||
|
add_dnsmasq_opt "server=$server"
|
||||||
|
add_dnsmasq_opt "no-resolv"
|
||||||
|
if [ "$report_client_info" = "1" ]; then
|
||||||
|
add_dnsmasq_opt "add-mac"
|
||||||
|
add_dnsmasq_opt "add-subnet=32,128"
|
||||||
|
fi
|
||||||
|
|
||||||
|
procd_open_instance
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
procd_set_param command "$PROG" run \
|
||||||
|
-listen="$listen" \
|
||||||
|
$host_config_args \
|
||||||
|
-config="$config" \
|
||||||
|
-report-client-info="$report_client_info" \
|
||||||
|
-hardened-privacy="$hardened_privacy" \
|
||||||
|
-log-queries="$log_queries"
|
||||||
|
procd_set_param stdout 1
|
||||||
|
procd_set_param stderr 1
|
||||||
|
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
|
||||||
|
procd_close_instance
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnsmasq_reload
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
rm -f /tmp/dnsmasq.d/nextdns.conf
|
||||||
|
dnsmasq_reload
|
||||||
|
}
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
procd_add_reload_trigger "nextdns"
|
||||||
|
}
|
107
net/radicale2/Makefile
Normal file
107
net/radicale2/Makefile
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=radicale2
|
||||||
|
PKG_VERSION:=2.1.11
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
PKG_MAINTAINER:=Daniel Dickinson <cshored@thecshore.com>
|
||||||
|
|
||||||
|
PKG_LICENSE:=GPL-3.0
|
||||||
|
PKG_LICENSE_FILES:=COPYING
|
||||||
|
PKG_CPE_ID:=cpe:/a:radicale:radicale
|
||||||
|
|
||||||
|
PKG_SOURCE:=Radicale-$(PKG_VERSION).tar.gz
|
||||||
|
PKG_SOURCE_URL:=https://files.pythonhosted.org/packages/source/R/Radicale/
|
||||||
|
PKG_HASH:=02273fcc6ae10e0f74aa12652e24d0001eec8dbf467d54ddb4dfcc2af7d7a5db
|
||||||
|
PKG_BUILD_DIR:=$(BUILD_DIR)/radicale2-$(BUILD_VARIANT)-$(PKG_VERSION)
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
include ../../lang/python/python3-package.mk
|
||||||
|
|
||||||
|
PKG_UNPACK:=$(HOST_TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xzf $(DL_DIR)/$(PKG_SOURCE)
|
||||||
|
|
||||||
|
define Package/radicale2/Default
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
SUBMENU:=Web Servers/Proxies
|
||||||
|
URL:=http://radicale.org/
|
||||||
|
TITLE:=Radicale 2.x CalDAV/CardDAV server
|
||||||
|
MAINTAINER:=Daniel Dickinson <cshored@thecshore.com>
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2
|
||||||
|
$(call Package/radicale2/Default)
|
||||||
|
USERID:=radicale2=225:radicale2=225
|
||||||
|
DEPENDS:=+python3 +python3-dateutil +python3-vobject +python3-setuptools
|
||||||
|
CONFLICTS:=radicale
|
||||||
|
VARIANT:=python3
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2-examples
|
||||||
|
$(call Package/radicale2/Default)
|
||||||
|
TITLE:=Radicale v2 example configs
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2-meta/description
|
||||||
|
The Radicale Project is a CalDAV (calendar) and CardDAV (contact) server. It aims to be a light solution, easy to use, easy to install, easy to configure. As a consequence, it requires few software dependances and is pre-configured to work out-of-the-box.
|
||||||
|
|
||||||
|
The Radicale Project runs on most of the UNIX-like platforms (Linux, BSD, MacOS X) and Windows. It is known to work with Evolution, Lightning, iPhone and Android clients. It is free and open-source software, released under GPL version 3.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2/description
|
||||||
|
$(call Package/radicale2-meta/description)
|
||||||
|
.
|
||||||
|
This package contains the python files.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2-examples/description
|
||||||
|
$(call Package/radicale2-meta/description)
|
||||||
|
.
|
||||||
|
This package contains upstream configs for example purposes.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2/conffiles
|
||||||
|
/etc/config/radicale2
|
||||||
|
/etc/radicale2/config
|
||||||
|
/etc/radicale2/users
|
||||||
|
/etc/radicale2/rights
|
||||||
|
/etc/radicale2/logging
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2/preinst
|
||||||
|
#!/bin/sh
|
||||||
|
[ -n "$${IPKG_INSTROOT}" ] && exit 0 # if run within buildroot exit
|
||||||
|
|
||||||
|
# stop service if PKG_UPGRADE
|
||||||
|
[ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/radicale2 stop >/dev/null 2>&1
|
||||||
|
|
||||||
|
exit 0 # suppress errors from stop command
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Py3Package/radicale2/filespec
|
||||||
|
+|$(PYTHON3_PKG_DIR)
|
||||||
|
+|/usr/bin/radicale2|0755
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Py3Package/radicale2/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/radicale $(PKG_INSTALL_DIR)/usr/bin/radicale2
|
||||||
|
$(SED) 's,^#!.*python.*,#!/usr/bin/python$(PYTHON3_VERSION),' $(PKG_INSTALL_DIR)/usr/bin/radicale2
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d
|
||||||
|
$(INSTALL_CONF) ./files/radicale2.config $(1)/etc/config/radicale2
|
||||||
|
$(INSTALL_BIN) ./files/radicale2.init $(1)/etc/init.d/radicale2
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/radicale2-examples/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/share/radicale2
|
||||||
|
$(INSTALL_DATA) $(PKG_BUILD_DIR)/config $(1)/usr/share/radicale2/config.example
|
||||||
|
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rights $(1)/usr/share/radicale2/rights.example
|
||||||
|
$(INSTALL_DATA) $(PKG_BUILD_DIR)/logging $(1)/usr/share/radicale2/logging.example
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call Py3Package,radicale2))
|
||||||
|
$(eval $(call BuildPackage,radicale2))
|
||||||
|
$(eval $(call BuildPackage,radicale2-src))
|
||||||
|
$(eval $(call BuildPackage,radicale2-examples))
|
7
net/radicale2/files/radicale2.config
Normal file
7
net/radicale2/files/radicale2.config
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#config section server
|
||||||
|
# list host 127.0.0.1:5232
|
||||||
|
# list host ::1:5232
|
||||||
|
|
||||||
|
#config user
|
||||||
|
#option name user1
|
||||||
|
#option password password1
|
278
net/radicale2/files/radicale2.init
Executable file
278
net/radicale2/files/radicale2.init
Executable file
@ -0,0 +1,278 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
START=80
|
||||||
|
STOP=10
|
||||||
|
|
||||||
|
CFGDIR=/var/etc/radicale2
|
||||||
|
SYSCFG=$CFGDIR/config
|
||||||
|
USRCFG=$CFGDIR/users
|
||||||
|
|
||||||
|
DATADIR="/srv/radicale2/data"
|
||||||
|
LOGDIR=""
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
# we could start with empty configuration file using defaults
|
||||||
|
[ -f ${IPKG_INSTROOT}/etc/config/radicale2 ] || touch ${IPKG_INSTROOT}/etc/config/radicale2
|
||||||
|
|
||||||
|
conf_line() {
|
||||||
|
local cfgfile="$1"
|
||||||
|
local option="$2"
|
||||||
|
local value="$3"
|
||||||
|
|
||||||
|
if [ -n "$value" ]; then
|
||||||
|
eval "echo '$2' = '$value' >>'$cfgfile'"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_getline() {
|
||||||
|
local cfg="$1"
|
||||||
|
local cfgfile="$2"
|
||||||
|
local option="$3"
|
||||||
|
local defval="$4"
|
||||||
|
local flag="$5"
|
||||||
|
unset value
|
||||||
|
|
||||||
|
if [ "$flag" != "1" ]; then
|
||||||
|
config_get value "$cfg" "$option" "$defval"
|
||||||
|
conf_line "$cfgfile" "$option" "$value"
|
||||||
|
else
|
||||||
|
config_get_bool value "$cfg" "$option" "$defval"
|
||||||
|
[ -z "$defval" ] && defval=1
|
||||||
|
if [ "$value" -ne "$defval" ]; then
|
||||||
|
if [ "$value" -ne 0 ]; then
|
||||||
|
conf_line "$cfgfile" "$option" "True"
|
||||||
|
else
|
||||||
|
conf_line "$cfgfile" "$option" "False"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_hosts_line() {
|
||||||
|
local val="$1"
|
||||||
|
|
||||||
|
append hostlist "$val" ", "
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_section() {
|
||||||
|
local cfg="$1"
|
||||||
|
local cfgfile="$2"
|
||||||
|
local hostlist=""
|
||||||
|
local value
|
||||||
|
|
||||||
|
echo "[$cfg]
|
||||||
|
" >>$cfgfile
|
||||||
|
|
||||||
|
case $cfg in
|
||||||
|
server)
|
||||||
|
config_list_foreach "$cfg" host build_hosts_line
|
||||||
|
conf_line "$tmpfile" hosts "$hostlist"
|
||||||
|
conf_getline "$cfg" $tmpfile max_connections
|
||||||
|
conf_getline "$cfg" $tmpfile max_conntent_length
|
||||||
|
conf_getline "$cfg" $tmpfile timeout
|
||||||
|
|
||||||
|
conf_getline "$cfg" $tmpfile ssl 0 1
|
||||||
|
if [ "$value" -eq 1 ]; then
|
||||||
|
conf_getline "$cfg" $tmpfile certificate
|
||||||
|
conf_getline "$cfg" $tmpfile key
|
||||||
|
conf_getline "$cfg" $tmpfile certificate_authority
|
||||||
|
conf_getline "$cfg" $tmpfile protocol
|
||||||
|
conf_getline "$cfg" $tmpfile ciphers
|
||||||
|
fi
|
||||||
|
|
||||||
|
conf_getline "$cfg" $tmpfile dns_lookup 1 1
|
||||||
|
conf_getline "$cfg" $tmpfile realm
|
||||||
|
;;
|
||||||
|
encoding)
|
||||||
|
conf_getline "$cfg" $tmpfile request
|
||||||
|
conf_getline "$cfg" $tmpfile stock
|
||||||
|
;;
|
||||||
|
auth)
|
||||||
|
conf_getline "$cfg" $tmpfile "type" htpasswd
|
||||||
|
if [ "$value" = "htpasswd" ]; then
|
||||||
|
conf_getline "$cfg" $tmpfile htpasswd_filename $CFGDIR/users
|
||||||
|
conf_getline "$cfg" "$tmpfile" htpasswd_encryption plain
|
||||||
|
fi
|
||||||
|
|
||||||
|
conf_getline "$cfg" "$tmpfile" delay
|
||||||
|
;;
|
||||||
|
rights)
|
||||||
|
conf_getline "$cfg" "$tmpfile" "type"
|
||||||
|
if [ "$value" = "from_file" ]; then
|
||||||
|
conf_getline "$cfg" "$tmpfile" "file"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
storage)
|
||||||
|
conf_getline "$cfg" $tmpfile filesystem_folder "$DATADIR"
|
||||||
|
DATADIR="$value"
|
||||||
|
conf_getline "$cfg" $tmpfile filesystem_locking 1 1
|
||||||
|
conf_getline "$cfg" $tmpfile max_sync_token_age
|
||||||
|
conf_getline "$cfg" $tmpfile filesystem_close_lock_file 0 1
|
||||||
|
conf_getline "$cfg" $tmpfile hook
|
||||||
|
;;
|
||||||
|
web)
|
||||||
|
conf_getline "$cfg" $tmpfile "type"
|
||||||
|
;;
|
||||||
|
logging)
|
||||||
|
conf_getline "$cfg" "$tmpfile" config
|
||||||
|
conf_getline "$cfg" "$tmpfile" debug 0 1
|
||||||
|
conf_getline "$cfg" "$tmpfile" full_environment 0 1
|
||||||
|
conf_getline "$cfg" "$tmpfile" mask_passwords 1 1
|
||||||
|
;;
|
||||||
|
headers)
|
||||||
|
config_get "$cfg" "$tmpfile" cors
|
||||||
|
if [ -n "$cors" ]; then
|
||||||
|
echo "Access-Control-Allow-Origin = $cors" >>$tmpfile
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "
|
||||||
|
" >>$cfgfile
|
||||||
|
}
|
||||||
|
|
||||||
|
add_missing_sections() {
|
||||||
|
local cfgfile="$1"
|
||||||
|
|
||||||
|
for section in server encoding auth rights storage web logging headers; do
|
||||||
|
if [ "$section" = "server" ]; then
|
||||||
|
grep -q "\[$section\]" $cfgfile || echo "
|
||||||
|
[$section]
|
||||||
|
hosts = 0.0.0.0:5232, [::]:5232
|
||||||
|
|
||||||
|
" >>$cfgfile
|
||||||
|
elif [ "$section" = "auth" ]; then
|
||||||
|
grep -q "\[$section\]" $cfgfile || echo "
|
||||||
|
[$section]
|
||||||
|
type = htpasswd
|
||||||
|
htpasswd_filename = $CFGDIR/users
|
||||||
|
htpasswd_encryption = plain
|
||||||
|
|
||||||
|
" >>$cfgfile
|
||||||
|
elif [ "$section" = "storage" ]; then
|
||||||
|
grep -q "\[$section\]" $cfgfile || echo "
|
||||||
|
[$section]
|
||||||
|
filesystem_folder = $DATADIR
|
||||||
|
|
||||||
|
" >>$cfgfile
|
||||||
|
else
|
||||||
|
grep -q "\[$section\]" $cfgfile || echo "
|
||||||
|
[$section]
|
||||||
|
|
||||||
|
" >>$cfgfile
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
add_user() {
|
||||||
|
local cfg="$1"
|
||||||
|
local tmpfile="$2"
|
||||||
|
local name password
|
||||||
|
|
||||||
|
config_get name "$cfg" name
|
||||||
|
config_get password "$cfg" password
|
||||||
|
|
||||||
|
[ -n "$name" ] && echo "$name:$password" >>$tmpfile
|
||||||
|
}
|
||||||
|
|
||||||
|
build_users() {
|
||||||
|
local tmpfile="$1"
|
||||||
|
|
||||||
|
# temporary config file
|
||||||
|
# radicale2 needs read access
|
||||||
|
chmod 0640 $tmpfile
|
||||||
|
|
||||||
|
config_foreach add_user user "$tmpfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_config() {
|
||||||
|
local tmpfile=$(mktemp)
|
||||||
|
local tmpfile2=$(mktemp)
|
||||||
|
|
||||||
|
# temporary config file
|
||||||
|
# radicale2 need read access
|
||||||
|
chmod 0640 $tmpfile
|
||||||
|
|
||||||
|
config_load radicale2
|
||||||
|
config_foreach conf_section section $tmpfile
|
||||||
|
add_missing_sections $tmpfile
|
||||||
|
|
||||||
|
build_users $tmpfile2
|
||||||
|
|
||||||
|
# move tmp to final
|
||||||
|
mkdir -m0750 -p $CFGDIR
|
||||||
|
cat $tmpfile >$SYSCFG
|
||||||
|
rm -f $tmpfile
|
||||||
|
cat $tmpfile2 >$USRCFG
|
||||||
|
rm -f $tmpfile2
|
||||||
|
}
|
||||||
|
|
||||||
|
set_permission() {
|
||||||
|
# config file permissions (read access for group)
|
||||||
|
chmod 0750 $CFGDIR
|
||||||
|
chmod 0640 $SYSCFG
|
||||||
|
chmod 0640 $USRCFG
|
||||||
|
chgrp -R radicale2 $CFGDIR
|
||||||
|
# data directory does not exist
|
||||||
|
[ -d $DATADIR ] || {
|
||||||
|
logger -p user.error -t "radicale2[----]" "Data directory '$DATADIR' does not exist. Startup failed !!!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface_triggers() {
|
||||||
|
local action="$1"
|
||||||
|
local triggerlist trigger
|
||||||
|
|
||||||
|
config_load radicale2
|
||||||
|
config_get triggerlist server triggerlist
|
||||||
|
|
||||||
|
. /lib/functions/network.sh
|
||||||
|
|
||||||
|
if [ -n "$triggerlist" ]; then
|
||||||
|
for trigger in $triggerlist; do
|
||||||
|
if [ "$action" = "add_trigger" ]; then
|
||||||
|
procd_add_interface_trigger "interface.*" "$trigger" /etc/init.d/radicale2 reload
|
||||||
|
else
|
||||||
|
network_is_up "$trigger" && return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
if [ "$action" = "add_trigger" ]; then
|
||||||
|
procd_add_raw_trigger "interface.*.up" 2000 /etc/init.d/radicale2 reload
|
||||||
|
else
|
||||||
|
ubus call network.device status | grep -q '"up": true' && return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
[ "$action" = "add_trigger" ] || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
local haveinterface
|
||||||
|
|
||||||
|
if [ ! -r /etc/radicale2/config ]; then
|
||||||
|
build_config
|
||||||
|
set_permission
|
||||||
|
fi
|
||||||
|
|
||||||
|
interface_triggers "check_interface_up" || return
|
||||||
|
|
||||||
|
procd_open_instance "radicale2"
|
||||||
|
procd_set_param respawn
|
||||||
|
procd_set_param stderr 1
|
||||||
|
procd_set_param stdout 1
|
||||||
|
if [ ! -r /etc/radicale2/config ]; then
|
||||||
|
procd_set_param command /usr/bin/radicale2 --config="$SYSCFG"
|
||||||
|
else
|
||||||
|
procd_set_param command /usr/bin/radicale2 --config="/etc/radicale2/config"
|
||||||
|
fi
|
||||||
|
procd_set_param user radicale2
|
||||||
|
procd_close_instance
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
interface_triggers "add_trigger"
|
||||||
|
procd_add_reload_trigger "radicale2"
|
||||||
|
}
|
13
net/radicale2/patches/110-disable-setup_requirements.patch
Normal file
13
net/radicale2/patches/110-disable-setup_requirements.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Index: radicale2-python3-2.1.11/setup.py
|
||||||
|
===================================================================
|
||||||
|
--- radicale2-python3-2.1.11.orig/setup.py
|
||||||
|
+++ radicale2-python3-2.1.11/setup.py
|
||||||
|
@@ -67,7 +67,7 @@ setup(
|
||||||
|
package_data={"radicale": WEB_FILES},
|
||||||
|
entry_points={"console_scripts": ["radicale = radicale.__main__:run"]},
|
||||||
|
install_requires=["vobject>=0.9.6", "python-dateutil>=2.7.3"],
|
||||||
|
- setup_requires=pytest_runner,
|
||||||
|
+ setup_requires=[],
|
||||||
|
tests_require=tests_require,
|
||||||
|
extras_require={
|
||||||
|
"test": tests_require,
|
52
net/rosy-file-server/Makefile
Normal file
52
net/rosy-file-server/Makefile
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2019 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=rosy-file-server
|
||||||
|
PKG_VERSION:=1.0.0
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Rosy Song <rosysong@rosinson.com>
|
||||||
|
|
||||||
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/rosy-file-server
|
||||||
|
SUBMENU:=File Transfer
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
TITLE:=Rosy File Server over HTTP
|
||||||
|
PKGARCH:=all
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/rosy-file-server/description
|
||||||
|
This package is a configuration management for luci-app-rosy-file-server.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/rosy-file-server/conffiles
|
||||||
|
/etc/config/rosy-file-server
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Configure
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/rosy-file-server/install
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config
|
||||||
|
$(INSTALL_BIN) ./files/rosyfs.init $(1)/etc/init.d/rosyfs
|
||||||
|
$(INSTALL_CONF) ./files/rosyfs.config $(1)/etc/config/rosyfs
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,rosy-file-server))
|
13
net/rosy-file-server/files/rosyfs.config
Normal file
13
net/rosy-file-server/files/rosyfs.config
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2019 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
config rosyfs default
|
||||||
|
|
||||||
|
# Web title
|
||||||
|
option title 'Rosy File Server'
|
||||||
|
|
||||||
|
# Path to share
|
||||||
|
option target '/www'
|
||||||
|
|
||||||
|
option disabled '0'
|
29
net/rosy-file-server/files/rosyfs.init
Executable file
29
net/rosy-file-server/files/rosyfs.init
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
#
|
||||||
|
# Copyright (C) 2019 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
START=99
|
||||||
|
USE_PROCD=1
|
||||||
|
SHARE_PATH=/www/rosyfs-share
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
procd_add_reload_trigger rosyfs
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
config_load rosyfs
|
||||||
|
config_get disabled default disabled '0'
|
||||||
|
config_get target default target ''
|
||||||
|
|
||||||
|
[ $disabled -eq 1 ] && return
|
||||||
|
|
||||||
|
[ -n "$target" -a ! "$(readlink $SHARE_PATH)" = "$target" ] && {
|
||||||
|
rm -f $SHARE_PATH
|
||||||
|
ln -s $target $SHARE_PATH
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
rm -f $SHARE_PATH
|
||||||
|
}
|
@ -8,63 +8,117 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=unbound
|
PKG_NAME:=unbound
|
||||||
PKG_VERSION:=1.8.1
|
PKG_VERSION:=1.9.5
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
|
PKG_SOURCE_URL:=https://nlnetlabs.nl/downloads/unbound
|
||||||
|
PKG_HASH:=8a8d400f697c61d73d109c250743a1b6b79848297848026d82b43e831045db57
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Eric Luehrsen <ericluehrsen@gmail.com>
|
||||||
PKG_LICENSE:=BSD-3-Clause
|
PKG_LICENSE:=BSD-3-Clause
|
||||||
PKG_LICENSE_FILES:=LICENSE
|
PKG_LICENSE_FILES:=LICENSE
|
||||||
PKG_MAINTAINER:=Eric Luehrsen <ericluehrsen@gmail.com>
|
PKG_CPE_ID:=cpe:/a:nlnetlabs:unbound
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
|
||||||
PKG_SOURCE_URL:=http://www.unbound.net/downloads
|
|
||||||
PKG_HASH:=c362b3b9c35d1b8c1918da02cdd5528d729206c14c767add89ae95acae363c5d
|
|
||||||
|
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
PKG_FIXUP:=autoreconf
|
PKG_FIXUP:=autoreconf
|
||||||
PKG_INSTALL:=1
|
PKG_INSTALL:=1
|
||||||
|
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define Package/unbound/Default
|
define Package/unbound/Default
|
||||||
TITLE:=Validating Recursive DNS Server
|
|
||||||
URL:=http://www.unbound.net/
|
|
||||||
DEPENDS:=+libopenssl
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Package/unbound
|
|
||||||
$(call Package/unbound/Default)
|
|
||||||
SECTION:=net
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
SUBMENU:=IP Addresses and Names
|
SUBMENU:=IP Addresses and Names
|
||||||
USERID:=unbound=553:unbound=553
|
USERID:=unbound:unbound
|
||||||
TITLE+= (daemon)
|
TITLE:=Recursive DNS Server
|
||||||
DEPENDS+= +libunbound
|
URL:=https://nlnetlabs.nl/projects/unbound/about
|
||||||
|
DEPENDS:=+libopenssl +@OPENSSL_WITH_EC
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/unbound/description
|
define Package/unbound-daemon
|
||||||
This package contains the Unbound daemon.
|
$(call Package/unbound/Default)
|
||||||
|
TITLE+= (daemon, light traffic)
|
||||||
|
DEPENDS+= +libunbound
|
||||||
|
VARIANT:=light
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/unbound-daemon/description
|
||||||
|
This package contains the Unbound daemon with basic includes
|
||||||
|
necessary to meet the needs of UCI/LuCI configuration optoins.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/unbound-daemon-heavy
|
||||||
|
$(call Package/unbound/Default)
|
||||||
|
TITLE+= (daemon, heavy traffic)
|
||||||
|
URL:=https://nlnetlabs.nl/documentation/unbound/howto-optimise
|
||||||
|
DEPENDS+= +libunbound-heavy +libpthread +libevent2 +libevent2-pthreads
|
||||||
|
VARIANT:=heavy
|
||||||
|
PROVIDES:=unbound-daemon
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/unbound-daemon-heavy/description
|
||||||
|
This package contains the Unbound daemon including 'libevent' and
|
||||||
|
'libpthread' to better handle large networks with heavy query loads.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/libunbound
|
||||||
|
$(call Package/unbound/Default)
|
||||||
|
SECTION:=libs
|
||||||
|
CATEGORY:=Libraries
|
||||||
|
SUBMENU:=Networking
|
||||||
|
TITLE+= (library, light traffic)
|
||||||
|
VARIANT:=light
|
||||||
|
DEFAULT_VARIANT:=1
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/libunbound/description
|
||||||
|
This package contains the Unbound shared library with basic includes
|
||||||
|
necessary to meet the needs of UCI/LuCI configuration optoins.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/libunbound-heavy
|
||||||
|
$(call Package/unbound/Default)
|
||||||
|
SECTION:=libs
|
||||||
|
CATEGORY:=Libraries
|
||||||
|
SUBMENU:=Networking
|
||||||
|
TITLE+= (library, heavy traffic)
|
||||||
|
URL:=https://nlnetlabs.nl/documentation/unbound/howto-optimise
|
||||||
|
DEPENDS+= +libpthread +libevent2 +libevent2-pthreads
|
||||||
|
VARIANT:=heavy
|
||||||
|
PROVIDES:=libunbound
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/libunbound-heavy/description
|
||||||
|
This package contains the Unbound shared library including 'libevent' and
|
||||||
|
'libpthread' to better handle large networks with heavy query loads.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/unbound-anchor
|
define Package/unbound-anchor
|
||||||
$(call Package/unbound/Default)
|
$(call Package/unbound/Default)
|
||||||
SECTION:=net
|
TITLE+= (root DSKEY)
|
||||||
CATEGORY:=Network
|
DEPENDS+= +unbound-daemon +libexpat
|
||||||
SUBMENU:=IP Addresses and Names
|
|
||||||
TITLE+= (DSKEY utility)
|
|
||||||
DEPENDS+= +unbound +libexpat
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/unbound-anchor/description
|
define Package/unbound-anchor/description
|
||||||
This package contains the Unbound anchor utility.
|
This package contains the Unbound anchor utility.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/unbound-checkconf
|
||||||
|
$(call Package/unbound/Default)
|
||||||
|
TITLE+= (config checker)
|
||||||
|
DEPENDS+= +unbound-daemon
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/unbound-checkconf/description
|
||||||
|
This package contains the Unbound DNS configuration checker utility.
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/unbound-control
|
define Package/unbound-control
|
||||||
$(call Package/unbound/Default)
|
$(call Package/unbound/Default)
|
||||||
SECTION:=net
|
TITLE+= (remote control)
|
||||||
CATEGORY:=Network
|
DEPENDS+= +unbound-daemon
|
||||||
SUBMENU:=IP Addresses and Names
|
|
||||||
TITLE+= (control utility)
|
|
||||||
DEPENDS+= +unbound
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/unbound-control/description
|
define Package/unbound-control/description
|
||||||
@ -73,9 +127,6 @@ endef
|
|||||||
|
|
||||||
define Package/unbound-control-setup
|
define Package/unbound-control-setup
|
||||||
$(call Package/unbound/Default)
|
$(call Package/unbound/Default)
|
||||||
SECTION:=net
|
|
||||||
CATEGORY:=Network
|
|
||||||
SUBMENU:=IP Addresses and Names
|
|
||||||
TITLE+= (control setup)
|
TITLE+= (control setup)
|
||||||
DEPENDS+= +unbound-control +openssl-util
|
DEPENDS+= +unbound-control +openssl-util
|
||||||
endef
|
endef
|
||||||
@ -86,10 +137,7 @@ endef
|
|||||||
|
|
||||||
define Package/unbound-host
|
define Package/unbound-host
|
||||||
$(call Package/unbound/Default)
|
$(call Package/unbound/Default)
|
||||||
SECTION:=net
|
TITLE+= (DNS lookup)
|
||||||
CATEGORY:=Network
|
|
||||||
SUBMENU:=IP Addresses and Names
|
|
||||||
TITLE+= (lookup utility)
|
|
||||||
DEPENDS+= +libunbound
|
DEPENDS+= +libunbound
|
||||||
endef
|
endef
|
||||||
|
|
||||||
@ -97,52 +145,58 @@ define Package/unbound-host/description
|
|||||||
This package contains the Unbound DNS lookup utility.
|
This package contains the Unbound DNS lookup utility.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/libunbound
|
|
||||||
$(call Package/unbound/Default)
|
|
||||||
SECTION:=libs
|
|
||||||
CATEGORY:=Libraries
|
|
||||||
TITLE+= (library)
|
|
||||||
DEPENDS+= +libpthread
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Package/libunbound/description
|
|
||||||
This package contains the Unbound shared library.
|
|
||||||
endef
|
|
||||||
|
|
||||||
CONFIGURE_ARGS += \
|
CONFIGURE_ARGS += \
|
||||||
--disable-dsa \
|
--disable-dsa \
|
||||||
--disable-gost \
|
--disable-gost \
|
||||||
--enable-allsymbols \
|
--enable-allsymbols \
|
||||||
|
--enable-ecdsa \
|
||||||
--enable-tfo-client \
|
--enable-tfo-client \
|
||||||
--enable-tfo-server \
|
--enable-tfo-server \
|
||||||
--with-libexpat="$(STAGING_DIR)/usr" \
|
--with-libexpat="$(STAGING_DIR)/usr" \
|
||||||
--with-ssl="$(STAGING_DIR)/usr" \
|
--with-ssl="$(STAGING_DIR)/usr" \
|
||||||
--with-pidfile=/var/run/unbound.pid \
|
--with-user=unbound \
|
||||||
--with-user=unbound
|
--with-run-dir=/var/lib/unbound \
|
||||||
|
--with-conf-file=/var/lib/unbound/unbound.conf \
|
||||||
|
--with-pidfile=/var/run/unbound.pid
|
||||||
|
|
||||||
define Package/unbound/conffiles
|
ifeq ($(BUILD_VARIANT),heavy)
|
||||||
|
CONFIGURE_ARGS += \
|
||||||
|
--with-pthreads \
|
||||||
|
--with-libevent="$(STAGING_DIR)/usr" \
|
||||||
|
--enable-event-api
|
||||||
|
else
|
||||||
|
CONFIGURE_ARGS += \
|
||||||
|
--without-pthreads \
|
||||||
|
--without-solaris-threads \
|
||||||
|
--without-libevent
|
||||||
|
endif
|
||||||
|
|
||||||
|
define Package/unbound-daemon/conffiles
|
||||||
/etc/config/unbound
|
/etc/config/unbound
|
||||||
/etc/unbound/unbound.conf
|
/etc/unbound/unbound.conf
|
||||||
/etc/unbound/unbound_ext.conf
|
/etc/unbound/unbound_ext.conf
|
||||||
/etc/unbound/unbound_srv.conf
|
/etc/unbound/unbound_srv.conf
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
Package/unbound-daemon-heavy/conffiles = $(Package/unbound-daemon/conffiles)
|
||||||
|
|
||||||
define Build/InstallDev
|
define Build/InstallDev
|
||||||
$(INSTALL_DIR) $(1)/usr/include
|
|
||||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/unbound.h $(1)/usr/include/
|
|
||||||
$(INSTALL_DIR) $(1)/usr/lib
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libunbound.{so*,a,la} $(1)/usr/lib/
|
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libunbound.{so*,a,la} $(1)/usr/lib/
|
||||||
|
$(INSTALL_DIR) $(1)/usr/include
|
||||||
|
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/unbound.h $(1)/usr/include/
|
||||||
|
ifeq ($(BUILD_VARIANT),heavy)
|
||||||
|
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/unbound-event.h $(1)/usr/include/
|
||||||
|
endif
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/unbound/install
|
define Package/unbound-daemon/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
$(INSTALL_BIN) \
|
$(INSTALL_BIN) \
|
||||||
$(PKG_INSTALL_DIR)/usr/sbin/unbound \
|
$(PKG_INSTALL_DIR)/usr/sbin/unbound $(1)/usr/sbin/
|
||||||
$(PKG_INSTALL_DIR)/usr/sbin/unbound-checkconf \
|
|
||||||
$(1)/usr/sbin/
|
|
||||||
$(INSTALL_DIR) $(1)/etc/unbound
|
$(INSTALL_DIR) $(1)/etc/unbound
|
||||||
$(INSTALL_DATA) \
|
$(INSTALL_DATA) \
|
||||||
$(PKG_INSTALL_DIR)/etc/unbound/unbound.conf \
|
$(PKG_INSTALL_DIR)/var/lib/unbound/unbound.conf \
|
||||||
$(1)/etc/unbound/unbound.conf
|
$(1)/etc/unbound/unbound.conf
|
||||||
$(INSTALL_DATA) ./files/root.key $(1)/etc/unbound/root.key
|
$(INSTALL_DATA) ./files/root.key $(1)/etc/unbound/root.key
|
||||||
$(INSTALL_DATA) ./files/unbound_ext.conf $(1)/etc/unbound/unbound_ext.conf
|
$(INSTALL_DATA) ./files/unbound_ext.conf $(1)/etc/unbound/unbound_ext.conf
|
||||||
@ -159,15 +213,29 @@ define Package/unbound/install
|
|||||||
$(INSTALL_DATA) ./files/iptools.sh $(1)/usr/lib/unbound/iptools.sh
|
$(INSTALL_DATA) ./files/iptools.sh $(1)/usr/lib/unbound/iptools.sh
|
||||||
$(INSTALL_BIN) ./files/odhcpd.sh $(1)/usr/lib/unbound/odhcpd.sh
|
$(INSTALL_BIN) ./files/odhcpd.sh $(1)/usr/lib/unbound/odhcpd.sh
|
||||||
$(INSTALL_DATA) ./files/odhcpd.awk $(1)/usr/lib/unbound/odhcpd.awk
|
$(INSTALL_DATA) ./files/odhcpd.awk $(1)/usr/lib/unbound/odhcpd.awk
|
||||||
$(INSTALL_DATA) ./files/rootzone.sh $(1)/usr/lib/unbound/rootzone.sh
|
$(INSTALL_DATA) ./files/stopping.sh $(1)/usr/lib/unbound/stopping.sh
|
||||||
$(INSTALL_DATA) ./files/unbound.sh $(1)/usr/lib/unbound/unbound.sh
|
$(INSTALL_DATA) ./files/unbound.sh $(1)/usr/lib/unbound/unbound.sh
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
Package/unbound-daemon-heavy/install = $(Package/unbound-daemon/install)
|
||||||
|
|
||||||
|
define Package/libunbound/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libunbound.so.* $(1)/usr/lib/
|
||||||
|
endef
|
||||||
|
|
||||||
|
Package/libunbound-heavy/install = $(Package/libunbound/install)
|
||||||
|
|
||||||
define Package/unbound-anchor/install
|
define Package/unbound-anchor/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-anchor $(1)/usr/sbin/
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-anchor $(1)/usr/sbin/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/unbound-checkconf/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-checkconf $(1)/usr/sbin/
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/unbound-control/install
|
define Package/unbound-control/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-control $(1)/usr/sbin/
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-control $(1)/usr/sbin/
|
||||||
@ -183,15 +251,13 @@ define Package/unbound-host/install
|
|||||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-host $(1)/usr/sbin/
|
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/unbound-host $(1)/usr/sbin/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/libunbound/install
|
$(eval $(call BuildPackage,unbound-daemon))
|
||||||
$(INSTALL_DIR) $(1)/usr/lib
|
$(eval $(call BuildPackage,unbound-daemon-heavy))
|
||||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libunbound.so.* $(1)/usr/lib/
|
$(eval $(call BuildPackage,libunbound))
|
||||||
endef
|
$(eval $(call BuildPackage,libunbound-heavy))
|
||||||
|
|
||||||
$(eval $(call BuildPackage,unbound))
|
|
||||||
$(eval $(call BuildPackage,unbound-anchor))
|
$(eval $(call BuildPackage,unbound-anchor))
|
||||||
|
$(eval $(call BuildPackage,unbound-checkconf))
|
||||||
$(eval $(call BuildPackage,unbound-control))
|
$(eval $(call BuildPackage,unbound-control))
|
||||||
$(eval $(call BuildPackage,unbound-control-setup))
|
$(eval $(call BuildPackage,unbound-control-setup))
|
||||||
$(eval $(call BuildPackage,unbound-host))
|
$(eval $(call BuildPackage,unbound-host))
|
||||||
$(eval $(call BuildPackage,libunbound))
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
## Package Overview
|
## Package Overview
|
||||||
OpenWrt default build uses [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) for DNS forwarding and DHCP. With a forward only resolver, dependence on the upstream recursors may be cause for concern. They are often provided by the ISP, and some users have switched to public DNS providers. Either way may result in problems due to performance, "snoop-vertising", hijacking (MiM), and other causes. Running a recursive resolver or resolver capable of TLS may be a solution.
|
OpenWrt default build uses [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) for DNS forwarding and DHCP. With a forward only resolver, dependence on the upstream recursors may be cause for concern. They are often provided by the ISP, and some users have switched to public DNS providers. Either way may result in problems due to performance, "snoop-vertising", hijacking (MiM), and other causes. Running a recursive resolver or resolver capable of TLS may be a solution.
|
||||||
|
|
||||||
Unbound may be useful on consumer grade embedded hardware. It is fully DNSSEC and TLS capable. It is _intended_ to be a recursive resolver only. [NLnet Labs NSD](https://www.nlnetlabs.nl/projects/nsd/) is _intended_ for the authoritative task. This is different than [ISC Bind](https://www.isc.org/downloads/bind/) and its inclusive functions. Unbound configuration effort and memory consumption may be easier to control. A consumer could have their own recursive resolver with 8/64 MB router, and remove potential issues from forwarding resolvers outside of their control.
|
Unbound may be useful on consumer grade embedded hardware. It is fully DNSSEC and TLS capable. It is _intended_ to be a recursive resolver only. NLnet Labs [NSD](https://www.nlnetlabs.nl/projects/nsd/) is _intended_ for the authoritative task. This is different than [ISC Bind](https://www.isc.org/downloads/bind/) and its inclusive functions. Unbound configuration effort and memory consumption may be easier to control. A consumer could have their own recursive resolver with 8/64 MB router, and remove potential issues from forwarding resolvers outside of their control.
|
||||||
|
|
||||||
This package builds on Unbounds capabilities with OpenWrt UCI. Not every Unbound option is in UCI, but rather, UCI simplifies the combination of related options. Unbounds native options are bundled and balanced within a smaller set of choices. Options include resources, DNSSEC, access control, and some TTL tweaking. The UCI also provides an escape option and works at the raw "unbound.conf" level.
|
This package builds on Unbounds capabilities with OpenWrt UCI. Not every Unbound option is in UCI, but rather, UCI simplifies the combination of related options. Unbounds native options are bundled and balanced within a smaller set of choices. Options include resources, DNSSEC, access control, and some TTL tweaking. The UCI also provides an escape option and works at the raw "unbound.conf" level.
|
||||||
|
|
||||||
@ -18,21 +18,21 @@ A few tweaks may be needed to enhance the realiability and effectiveness. Ad Blo
|
|||||||
**/etc/config/firewall**:
|
**/etc/config/firewall**:
|
||||||
```
|
```
|
||||||
config rule
|
config rule
|
||||||
option name 'Block-Public-DNS'
|
option name 'Block-Public-DNS'
|
||||||
option enabled '1'
|
option enabled '1'
|
||||||
option src 'lan'
|
option src 'lan'
|
||||||
option dest 'wan'
|
option dest 'wan'
|
||||||
option dest_port '53 853 5353'
|
option dest_port '53 853 5353'
|
||||||
option proto 'tcpudp'
|
option proto 'tcpudp'
|
||||||
option family 'any'
|
option family 'any'
|
||||||
option target 'REJECT'
|
option target 'REJECT'
|
||||||
```
|
```
|
||||||
|
|
||||||
## HOW TO: Integrate with DHCP
|
## HOW TO: Integrate with DHCP
|
||||||
Some UCI options and scripts help Unbound to work with DHCP servers to load the local DNS. The examples provided here are serial dnsmasq-unbound, parallel dnsmasq-unbound, and unbound scripted with odhcpd.
|
Some UCI options and scripts help Unbound to work with DHCP servers to load the local DNS. The examples provided here are serial dnsmasq-unbound, parallel dnsmasq-unbound, and unbound scripted with odhcpd.
|
||||||
|
|
||||||
### Serial dnsmasq
|
### Serial dnsmasq
|
||||||
In this case, dnsmasq is not changed *much* with respect to the default [OpenWrt configuration](https://openwrt.org/docs/guide-user/base-system/dns_configuration). Here dnsmasq is forced to use the local Unbound instance as the lone upstream DNS server, instead of your ISP. This may be the easiest implementation, but performance degradation can occur in high volume networks. dnsmasq and Unbound effectively have the same information in memory, and all transfers are double handled.
|
In this case, dnsmasq is not changed *much* with respect to the default [OpenWrt](https://openwrt.org/docs/guide-user/base-system/dns_configuration) configuration. Here dnsmasq is forced to use the local Unbound instance as the lone upstream DNS server, instead of your ISP. This may be the easiest implementation, but performance degradation can occur in high volume networks. Unbound and dnsmasq effectively have the same information in memory, and all transfers are double handled.
|
||||||
|
|
||||||
**/etc/config/unbound**:
|
**/etc/config/unbound**:
|
||||||
```
|
```
|
||||||
@ -148,26 +148,44 @@ config unbound
|
|||||||
### Hybrid Manual/UCI
|
### Hybrid Manual/UCI
|
||||||
You like the UCI. Yet, you need to add some difficult to standardize options, or just are not ready to make a UCI request yet. The files `/etc/unbound/unbound_srv.conf` and `/etc/unbound/unbound_ext.conf` will be copied to Unbounds chroot directory and included during auto generation.
|
You like the UCI. Yet, you need to add some difficult to standardize options, or just are not ready to make a UCI request yet. The files `/etc/unbound/unbound_srv.conf` and `/etc/unbound/unbound_ext.conf` will be copied to Unbounds chroot directory and included during auto generation.
|
||||||
|
|
||||||
The former will be added to the end of the `server:` clause. The later will be added to the end of the file for extended `forward:` and `view:` clauses. You can also disable unbound-control in the UCI which only allows "localhost" connections unencrypted, and then add an encrypted remote `control:` clause.
|
The file `unbound_srv.conf` will be added into the `server:` clause. The file `unbound_ext.conf` will be added to the end of all configuration. It is for extended `forward-zone:`, `stub-zone:`, `auth-zone:`, and `view:` clauses. You can also disable unbound-control in the UCI which only allows "localhost" connections unencrypted, and then add an encrypted remote `control:` clause.
|
||||||
|
|
||||||
#### DNS over TLS
|
## HOW TO: Cache Zone Files
|
||||||
Some public servers are now offering DNS over TLS. Unbound supports acting as DNS over TLS forwarding client. You can use the override files to enable this funciton. Unbound will connect TLS without verifying keys unless you install `ca-bundle` package. Do **not** however forget to maintain the certification bundle. No connection or connection without verification will occur unless you use complete syntax with "@" and "#". See [Cloudflare](https://www.cloudflare.com/) DNS [1.1.1.1](https://1.1.1.1/) for example. Unbound makes a new TLS connection for each query. You limit this effect using large resource and aggressive recursion setting (big cache and prefetching). You can also set memory and recursion to default and edit `unbound_srv.conf` to suit your needs. UCI improvements are in progress but not ready in OpenWrt 18.06.
|
Unbound has the ability to AXFR a whole zone from an authoritative server to prefetch the zone. This can speed up access to common zones. Some may have special bandwidth concerns for DNSSEC overhead. The following is a generic example. UCI defaults include the [root](https://www.internic.net/domain/) zone, but it is disabled as a ready to go example.
|
||||||
|
|
||||||
**/etc/unbound/unbound_srv.conf**:
|
**/etc/config/unbound**:
|
||||||
```
|
```
|
||||||
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
|
config zone
|
||||||
|
option enabled '1'
|
||||||
|
option fallback '1'
|
||||||
|
option url_dir 'https://asset-management.it.example.com/zones/'
|
||||||
|
option zone_type 'auth_zone'
|
||||||
|
list server 'ns1.it.example.com'
|
||||||
|
list server 'ns2.it.example.com'
|
||||||
|
list zone_name 'example.com'
|
||||||
```
|
```
|
||||||
|
|
||||||
**/etc/unbound/unbound_ext.conf**:
|
## HOW TO: TLS Over DNS
|
||||||
|
Unbound can use TLS as a client or server. UCI supports Unbound as a forwarding client with TLS. Servers are more complex and need manual configuration. This may be desired for privacy against stealth tracking. Some public DNS servers seem to advertise help in this quest. If your looking for a better understanding, then some information can be found at [Cloudflare](https://www.cloudflare.com/) DNS [1.1.1.1](https://1.1.1.1/). The following is a generic example. You can mix providers by using complete server specificaiton to override the zones common port and certificate domain index.
|
||||||
|
|
||||||
|
Update as of Unbound 1.9.1, all TLS functions work correctly with either OpenSSL 1.0.2 or 1.1.0. Please be sure to install `ca-bundle` package and use `opkg` to get updates regularly.
|
||||||
|
|
||||||
|
**/etc/config/unbound**:
|
||||||
```
|
```
|
||||||
forward-zone:
|
config zone
|
||||||
# example for Cloudflare about July 2018
|
option enabled '1'
|
||||||
name: .
|
# question: do you want to recurse when TLS fails or not?
|
||||||
forward-addr: 1.1.1.1@853#cloudflare-dns.com
|
option fallback '0'
|
||||||
forward-addr: 1.0.0.1@853#cloudflare-dns.com
|
option tls_index 'dns.example.net'
|
||||||
forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
|
option tls_port '853'
|
||||||
forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
|
option tls_upstream '1'
|
||||||
forward-tls-upstream: yes
|
option zone_type 'forward_zone'
|
||||||
|
# these servers assume a common TLS port/index
|
||||||
|
list server '192.0.2.53'
|
||||||
|
list server '2001:db8::53'
|
||||||
|
# this alternate server is fully specified inline
|
||||||
|
list server '192.0.2.153@443#dns.alternate.example.org'
|
||||||
|
list zone_name '.'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Complete List of UCI Options
|
## Complete List of UCI Options
|
||||||
@ -194,18 +212,17 @@ config unbound
|
|||||||
4 - Above and interfaces named <iface>.<hostname>.<domain>
|
4 - Above and interfaces named <iface>.<hostname>.<domain>
|
||||||
|
|
||||||
option add_wan_fqdn '0'
|
option add_wan_fqdn '0'
|
||||||
Level. Same as previous option only this applies to the WAN. WAN
|
Level. Same as previous option only this applies to the WAN. WAN are
|
||||||
are inferred by a UCI `config dhcp` entry that contains the line
|
inferred by a UCI `config dhcp` entry that contains the 'option ignore 1'.
|
||||||
option ignore '1'.
|
|
||||||
|
|
||||||
option dns64 '0'
|
option dns64 '0'
|
||||||
Boolean. Enable DNS64 through Unbound in order to bridge networks
|
Boolean. Enable DNS64 through Unbound in order to bridge networks that are
|
||||||
that are IPV6 only and IPV4 only (see RFC6052).
|
IPV6 only and IPV4 only (see RFC6052).
|
||||||
|
|
||||||
option dns64_prefix '64:ff9b::/96'
|
option dns64_prefix '64:ff9b::/96'
|
||||||
IPV6 Prefix. The IPV6 prefix wrapped on the IPV4 address for DNS64.
|
IPV6 Prefix. The IPV6 prefix wrapped on the IPV4 address for DNS64. You
|
||||||
You should use RFC6052 "well known" address, unless you also
|
should use RFC6052 "well known" address, unless you also redirect to a proxy
|
||||||
redirect to a proxy or gateway for your NAT64.
|
or gateway for your NAT64.
|
||||||
|
|
||||||
option dhcp_link 'none'
|
option dhcp_link 'none'
|
||||||
Program Name. Link to one of the supported programs we have scripts
|
Program Name. Link to one of the supported programs we have scripts
|
||||||
@ -224,16 +241,16 @@ config unbound
|
|||||||
|
|
||||||
option domain_type 'static'
|
option domain_type 'static'
|
||||||
Unbound local-zone: <domain> <type>. This allows you to lock
|
Unbound local-zone: <domain> <type>. This allows you to lock
|
||||||
down or allow forwarding of your domain, your router host name
|
down or allow forwarding of the local zone. Notable types:
|
||||||
without suffix, and leakage of RFC6762 "local."
|
static - typical single router setup much like OpenWrt dnsmasq default
|
||||||
|
refuse - to answer overtly with DNS code REFUSED
|
||||||
|
deny - to drop queries for the local zone
|
||||||
|
transparent - to use your manually added forward-zone: or stub-zone: clause
|
||||||
|
|
||||||
option edns_size '1280'
|
option edns_size '1280'
|
||||||
Bytes. Extended DNS is necessary for DNSSEC. However, it can run
|
Bytes. Extended DNS is necessary for DNSSEC. However, it can run
|
||||||
into MTU issues. Use this size in bytes to manage drop outs.
|
into MTU issues. Use this size in bytes to manage drop outs.
|
||||||
|
|
||||||
option extended_luci '0'
|
|
||||||
Boolean. Extends a tab hierarchy in LuCI for advanced configuration.
|
|
||||||
|
|
||||||
option extended_stats '0'
|
option extended_stats '0'
|
||||||
Boolean. extended statistics are printed from unbound-control.
|
Boolean. extended statistics are printed from unbound-control.
|
||||||
Keeping track of more statistics takes time.
|
Keeping track of more statistics takes time.
|
||||||
@ -253,28 +270,34 @@ config unbound
|
|||||||
Boolean. Skip all this UCI nonsense. Manually edit the
|
Boolean. Skip all this UCI nonsense. Manually edit the
|
||||||
configuration. Make changes to /etc/unbound/unbound.conf.
|
configuration. Make changes to /etc/unbound/unbound.conf.
|
||||||
|
|
||||||
|
option num_threads '1'
|
||||||
|
Count. Enable multithreading with the "heavy traffic" variant. Base variant
|
||||||
|
spins each as whole proces and is not efficient. Two threads may be used,
|
||||||
|
but they use one shared cache slab. More edges into an industrial setup,
|
||||||
|
and UCI simplificaitons may not be appropriate.
|
||||||
|
|
||||||
option protocol 'mixed'
|
option protocol 'mixed'
|
||||||
Unbound can limit its protocol used for recursive queries.
|
Unbound can limit its protocol used for recursive queries.
|
||||||
ip4_only - limit issues if you do not have native IPv6
|
ip4_only - old fashioned IPv4 upstream and downstream
|
||||||
ip6_only - test environment only; could cauase problems
|
ip6_only - test environment only; could cauase problems
|
||||||
|
ip6_local - upstream IPv4 only and local network IPv4 and IPv6
|
||||||
ip6_prefer - both IPv4 and IPv6 but try IPv6 first
|
ip6_prefer - both IPv4 and IPv6 but try IPv6 first
|
||||||
mixed - both IPv4 and IPv6
|
mixed - both IPv4 and IPv6
|
||||||
default - Unbound built-in defaults
|
default - Unbound built-in defaults
|
||||||
|
|
||||||
option query_minimize '0'
|
option query_minimize '0'
|
||||||
Boolean. Enable a minor privacy option. Don't let each server know
|
Boolean. Enable a minor privacy option. Don't let each server know the next
|
||||||
the next recursion. Query one piece at a time.
|
recursion. Query one piece at a time.
|
||||||
|
|
||||||
option query_min_strict '0'
|
option query_min_strict '0'
|
||||||
Boolean. Query minimize is best effort and will fall back to normal
|
Boolean. Query minimize is best effort and will fall back to normal when it
|
||||||
when it must. This option prevents the fall back, but less than
|
must. This option prevents the fall back, but less than standard name
|
||||||
standard name servers will fail to resolve their domains.
|
servers will fail to resolve their domains.
|
||||||
|
|
||||||
option rebind_localhost '0'
|
option rebind_localhost '0'
|
||||||
Boolean. Prevent loopback "127.0.0.0/8" or "::1/128" responses.
|
Boolean. Prevent loopback "127.0.0.0/8" or "::1/128" responses. These may
|
||||||
These may used by black hole servers for good purposes like
|
used by black hole servers for good purposes like ad-blocking or parental
|
||||||
ad-blocking or parental access control. Obviously these responses
|
access control. Obviously these responses may be used to for bad purposes.
|
||||||
also can be used to for bad purposes.
|
|
||||||
|
|
||||||
option rebind_protection '1'
|
option rebind_protection '1'
|
||||||
Level. Block your local address responses from global DNS. A poisoned
|
Level. Block your local address responses from global DNS. A poisoned
|
||||||
@ -300,16 +323,16 @@ config unbound
|
|||||||
large - about double of medium
|
large - about double of medium
|
||||||
|
|
||||||
option root_age '9'
|
option root_age '9'
|
||||||
Days. >90 Disables. Age limit for Unbound root data like root
|
Days. >90 Disables. Age limit for Unbound root data like root DNSSEC key.
|
||||||
DNSSEC key. Unbound uses RFC 5011 to manage root key. This could
|
Unbound uses RFC 5011 to manage root key. This could harm flash ROM. This
|
||||||
harm flash ROM. This activity is mapped to "tmpfs," but every so
|
activity is mapped to "tmpfs," but every so often it needs to be copied back
|
||||||
often it needs to be copied back to flash for the next reboot.
|
to flash for the next reboot.
|
||||||
|
|
||||||
option ttl_min '120'
|
option ttl_min '120'
|
||||||
Seconds. Minimum TTL in cache. Recursion can be expensive without
|
Seconds. Minimum TTL in cache. Recursion can be expensive without cache. A
|
||||||
cache. A low TTL is normal for server migration. A low TTL can be
|
low TTL is normal for server migration. A low TTL can be abused for snoop-
|
||||||
abused for snoop-vertising (DNS hit counts; recording query IP).
|
vertising (DNS hit counts; recording query IP). Typical to configure maybe
|
||||||
Typical to configure maybe 0~300, but 1800 is the maximum accepted.
|
0~300, but 1800 is the maximum accepted.
|
||||||
|
|
||||||
option unbound_control '0'
|
option unbound_control '0'
|
||||||
Level. Enables unbound-control application access ports.
|
Level. Enables unbound-control application access ports.
|
||||||
@ -323,28 +346,87 @@ config unbound
|
|||||||
Boolean. Enable DNSSEC. Unbound names this the "validator" module.
|
Boolean. Enable DNSSEC. Unbound names this the "validator" module.
|
||||||
|
|
||||||
option validator_ntp '1'
|
option validator_ntp '1'
|
||||||
Boolean. Disable DNSSEC time checks at boot. Once NTP confirms
|
Boolean. Disable DNSSEC time checks at boot. Once NTP confirms global real
|
||||||
global real time, then DNSSEC is restarted at full strength. Many
|
time, then DNSSEC is restarted at full strength. Many embedded devices don't
|
||||||
embedded devices don't have a real time power off clock. NTP needs
|
have a real time power off clock. NTP needs DNS to resolve servers. This
|
||||||
DNS to resolve servers. This works around the chicken-and-egg.
|
works around the chicken-and-egg.
|
||||||
|
|
||||||
list domain_forward 'mail.my-isp.com'
|
option verbosity '1'
|
||||||
Domain. Do not recurse, but rather forward the domains to given DNS
|
Level. Sets Unbounds logging intensity.
|
||||||
servers found in resolve.conf.auto from WAN DHCP client. This may
|
|
||||||
provide better access to mirror servers in 'your neigborhood.' This
|
|
||||||
may be useful in keeping local organization lookups on local subnets.
|
|
||||||
|
|
||||||
list domain_insecure 'ntp.somewhere.org'
|
list domain_insecure 'ntp.somewhere.org'
|
||||||
Domain. Domains that you wish to skip DNSSEC. It is one way around NTP
|
Domain. Domains that you wish to skip DNSSEC. It is one way around NTP
|
||||||
chicken and egg. Your DHCP servered domains are automatically included.
|
chicken and egg. Your DHCP servered domains are automatically included.
|
||||||
|
|
||||||
list rebind_interface 'lan'
|
|
||||||
Interface (logical). Works with 'rebind_protection' options 2 and 3.
|
|
||||||
|
|
||||||
list trigger_interface 'lan' 'wan'
|
list trigger_interface 'lan' 'wan'
|
||||||
Interface (logical). This option is a work around for netifd/procd
|
Interface (logical). This option is a work around for netifd/procd
|
||||||
interaction with WAN DHCPv6. Minor RA or DHCP changes in IP6 can
|
interaction with WAN DHCPv6. Minor RA or DHCP changes in IP6 can cause
|
||||||
cause netifd to execute procd interface reload. Limit Unbound procd
|
netifd to execute procd interface reload. Limit Unbound procd triggers to
|
||||||
triggers to LAN and WAN (IP4 only) to prevent restart @2-3 minutes.
|
LAN and WAN (IP4 only) to prevent restart @2-3 minutes.
|
||||||
|
|
||||||
|
|
||||||
|
config zone
|
||||||
|
Create Unbounds forward-zone:, stub-zone:, or auth-zone: clauses
|
||||||
|
|
||||||
|
option enabled 1
|
||||||
|
Boolean. Enable the zone clause.
|
||||||
|
|
||||||
|
option fallback 1
|
||||||
|
Boolean. Permit normal recursion when the narrowly selected servers in this
|
||||||
|
zone are unresponsive or return empty responses. Disable, if there are
|
||||||
|
security concerns (forward only internal to organization).
|
||||||
|
|
||||||
|
option port 53
|
||||||
|
Port. Servers are contact on this port for plain DNS operations.
|
||||||
|
|
||||||
|
option resolv_conf 0
|
||||||
|
Boolean. Use "resolv.conf" as it was filled by the DHCP client. This can be
|
||||||
|
used to forward zones within your ISP (mail.example.net) or that have co-
|
||||||
|
located services (streamed-movies.example.com). Recursion may not yield the
|
||||||
|
most local result, but forwarding may instead.
|
||||||
|
|
||||||
|
option tls_index (n/a)
|
||||||
|
Domain. Name TLS certificates are signed for (dns.example.net). If this
|
||||||
|
option is ommitted, then Unbound will make connections but not validate.
|
||||||
|
|
||||||
|
option tls_port 853
|
||||||
|
Port. Servers are contact on this port for DNS over TLS operations.
|
||||||
|
|
||||||
|
option tls_upstream 0
|
||||||
|
Boolean. Use TLS to contact the zone server.
|
||||||
|
|
||||||
|
option url_dir
|
||||||
|
String. http or https path, directory part only, to the zone file for
|
||||||
|
auth_zone type only. Files "${zone_name}.zone" are expect in this path.
|
||||||
|
|
||||||
|
option zone_type (n/a)
|
||||||
|
State. Required field or the clause is effectively disabled. Check Unbound
|
||||||
|
documentation for clarity (unbound-conf).
|
||||||
|
auth_zone - prefetch whole zones from authoritative server (ICANN)
|
||||||
|
forward_zone - forward queries in these domains to the listed servers
|
||||||
|
stub_zone - force recursion of these domains to the listed servers
|
||||||
|
|
||||||
|
list server (n/a)
|
||||||
|
IP. Every zone must have one server. Stub and forward require IP to prevent
|
||||||
|
chicken and egg (due to UCI simplicity). Authoritative prefetch may use a
|
||||||
|
server name.
|
||||||
|
|
||||||
|
list zone_name
|
||||||
|
Domain. Every zone must represent some part of the DNS tree. It can be all
|
||||||
|
of it "." or you internal organization domain "example.com." Within each
|
||||||
|
zone clause all zone names will be matched to all servers.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Replaced Options
|
||||||
|
config unbound / option prefetch_root
|
||||||
|
List the domains in a zone with type auth_zone and fill in the server or url
|
||||||
|
fields. Root zones are ready but disabled in default install UCI.
|
||||||
|
|
||||||
|
config unbound / list domain_forward
|
||||||
|
List the domains in a zone with type forward_zone and enable the
|
||||||
|
resolv_conf option.
|
||||||
|
|
||||||
|
config unbound / list rebind_interface
|
||||||
|
Enable rebind_protection at 2 and all DHCP interfaces are also protected for
|
||||||
|
IPV6 GLA (parallel to subnets in add_local_fqdn).
|
||||||
|
|
||||||
|
@ -14,30 +14,53 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
UNBOUND_LIBDIR=/usr/lib/unbound
|
# where are we?
|
||||||
UNBOUND_VARDIR=/var/lib/unbound
|
UB_LIBDIR=/usr/lib/unbound
|
||||||
|
UB_VARDIR=/var/lib/unbound
|
||||||
|
UB_PIDFILE=/var/run/unbound.pid
|
||||||
|
|
||||||
UNBOUND_PIDFILE=/var/run/unbound.pid
|
# conf deconstructed
|
||||||
|
UB_TOTAL_CONF=$UB_VARDIR/unbound.conf
|
||||||
|
UB_CORE_CONF=$UB_VARDIR/server.conf.tmp
|
||||||
|
UB_HOST_CONF=$UB_VARDIR/host.conf.tmp
|
||||||
|
UB_DHCP_CONF=$UB_VARDIR/dhcp.conf
|
||||||
|
UB_ZONE_CONF=$UB_VARDIR/zone.conf.tmp
|
||||||
|
UB_CTRL_CONF=$UB_VARDIR/ctrl.conf.tmp
|
||||||
|
UB_SRVMASQ_CONF=$UB_VARDIR/dnsmasq_srv.conf.tmp
|
||||||
|
UB_EXTMASQ_CONF=$UB_VARDIR/dnsmasq_ext.conf.tmp
|
||||||
|
UB_SRV_CONF=$UB_VARDIR/unbound_srv.conf
|
||||||
|
UB_EXT_CONF=$UB_VARDIR/unbound_ext.conf
|
||||||
|
|
||||||
UNBOUND_SRV_CONF=$UNBOUND_VARDIR/unbound_srv.conf
|
# TLS keys
|
||||||
UNBOUND_EXT_CONF=$UNBOUND_VARDIR/unbound_ext.conf
|
UB_TLS_KEY_FILE="TLS server UCI not implemented"
|
||||||
UNBOUND_DHCP_CONF=$UNBOUND_VARDIR/unbound_dhcp.conf
|
UB_TLS_PEM_FILE="TLS server UCI not implemented"
|
||||||
UNBOUND_CONFFILE=$UNBOUND_VARDIR/unbound.conf
|
UB_TLS_FWD_FILE=$UB_VARDIR/ca-certificates.crt
|
||||||
|
UB_TLS_ETC_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||||
|
|
||||||
UNBOUND_KEYFILE=$UNBOUND_VARDIR/root.key
|
# start files
|
||||||
UNBOUND_HINTFILE=$UNBOUND_VARDIR/root.hints
|
UB_RKEY_FILE=$UB_VARDIR/root.key
|
||||||
UNBOUND_TIMEFILE=$UNBOUND_VARDIR/hotplug.time
|
UB_RHINT_FILE=$UB_VARDIR/root.hints
|
||||||
|
UB_TIME_FILE=$UB_VARDIR/hotplug.time
|
||||||
|
UB_SKIP_FILE=$UB_VARDIR/skip.time
|
||||||
|
|
||||||
UNBOUND_CTLKEY_FILE=$UNBOUND_VARDIR/unbound_control.key
|
# control app keys
|
||||||
UNBOUND_CTLPEM_FILE=$UNBOUND_VARDIR/unbound_control.pem
|
UB_CTLKEY_FILE=$UB_VARDIR/unbound_control.key
|
||||||
UNBOUND_SRVKEY_FILE=$UNBOUND_VARDIR/unbound_server.key
|
UB_CTLPEM_FILE=$UB_VARDIR/unbound_control.pem
|
||||||
UNBOUND_SRVPEM_FILE=$UNBOUND_VARDIR/unbound_server.pem
|
UB_SRVKEY_FILE=$UB_VARDIR/unbound_server.key
|
||||||
|
UB_SRVPEM_FILE=$UB_VARDIR/unbound_server.pem
|
||||||
##############################################################################
|
|
||||||
|
# similar default SOA / NS RR as Unbound uses for private ARPA zones
|
||||||
UNBOUND_ANCHOR=/usr/sbin/unbound-anchor
|
UB_XSER=$(( $( date +%s ) / 60 ))
|
||||||
UNBOUND_CONTROL=/usr/sbin/unbound-control
|
UB_XSOA="7200 IN SOA localhost. nobody.invalid. $UB_XSER 3600 1200 9600 300"
|
||||||
UNBOUND_CONTROL_CFG="$UNBOUND_CONTROL -c $UNBOUND_CONFFILE"
|
UB_XNS="7200 IN NS localhost."
|
||||||
|
UB_XTXT="7200 IN TXT \"comment=local intranet dns zone\""
|
||||||
|
UB_MTXT="7200 IN TXT \"comment=masked internet dns zone\""
|
||||||
|
UB_LTXT="7200 IN TXT \"comment=rfc6762 multicast dns zone\""
|
||||||
|
|
||||||
|
# helper apps
|
||||||
|
UB_ANCHOR=/usr/sbin/unbound-anchor
|
||||||
|
UB_CONTROL=/usr/sbin/unbound-control
|
||||||
|
UB_CONTROL_CFG="$UB_CONTROL -c $UB_TOTAL_CONF"
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
@ -23,6 +23,140 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
DM_D_WAN_FQDN=0
|
||||||
|
|
||||||
|
DM_LIST_KNOWN_ZONES="invalid"
|
||||||
|
DM_LIST_TRN_ZONES=""
|
||||||
|
DM_LIST_LOCAL_DATA=""
|
||||||
|
DM_LIST_LOCAL_PTR=""
|
||||||
|
DM_LIST_FWD_PORTS=""
|
||||||
|
DM_LIST_FWD_ZONES=""
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
create_local_zone() {
|
||||||
|
local target="$1"
|
||||||
|
local partial domain found
|
||||||
|
|
||||||
|
case $DM_LIST_TRN_ZONES in
|
||||||
|
*"${target}"*)
|
||||||
|
found=1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
case $target in
|
||||||
|
[A-Za-z0-9]*.[A-Za-z0-9]*)
|
||||||
|
found=0
|
||||||
|
;;
|
||||||
|
|
||||||
|
*) # no dots
|
||||||
|
found=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
if [ $found -eq 0 ] ; then
|
||||||
|
# New Zone! Bundle local-zones: by first two name tiers "abcd.tld."
|
||||||
|
partial=$( echo "$target" | awk -F. '{ j=NF ; i=j-1; print $i"."$j }' )
|
||||||
|
DM_LIST_TRN_ZONES="$DM_LIST_TRN_ZONES $partial"
|
||||||
|
DM_LIST_KNOWN_ZONES="$DM_LIST_KNOWN_ZONES $partial"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
create_host_record() {
|
||||||
|
local cfg="$1"
|
||||||
|
local ip name debug_ip
|
||||||
|
|
||||||
|
# basefiles dhcp "domain" clause which means host A, AAAA, and PRT record
|
||||||
|
config_get ip "$cfg" ip
|
||||||
|
config_get name "$cfg" name
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$name" ] && [ -n "$ip" ] ; then
|
||||||
|
create_local_zone "$name"
|
||||||
|
|
||||||
|
|
||||||
|
case $ip in
|
||||||
|
fe[89ab][0-9a-f]:*|169.254.*)
|
||||||
|
debug_ip="$ip@$name"
|
||||||
|
;;
|
||||||
|
|
||||||
|
[1-9a-f]*:*[0-9a-f])
|
||||||
|
DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@AAAA@@$ip"
|
||||||
|
DM_LIST_LOCAL_PTR="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
|
||||||
|
;;
|
||||||
|
|
||||||
|
[1-9]*.*[0-9])
|
||||||
|
DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@A@@$ip"
|
||||||
|
DM_LIST_LOCAL_PTR="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
create_mx_record() {
|
||||||
|
local cfg="$1"
|
||||||
|
local domain relay pref record
|
||||||
|
|
||||||
|
# Insert a static MX record
|
||||||
|
config_get domain "$cfg" domain
|
||||||
|
config_get relay "$cfg" relay
|
||||||
|
config_get pref "$cfg" pref 10
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$domain" ] && [ -n "$relay" ] ; then
|
||||||
|
create_local_zone "$domain"
|
||||||
|
record="$domain.@@300@@IN@@MX@@$pref@@$relay."
|
||||||
|
DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
create_srv_record() {
|
||||||
|
local cfg="$1"
|
||||||
|
local srv target port class weight record
|
||||||
|
|
||||||
|
# Insert a static SRV record such as SIP server
|
||||||
|
config_get srv "$cfg" srv
|
||||||
|
config_get target "$cfg" target
|
||||||
|
config_get port "$cfg" port
|
||||||
|
config_get class "$cfg" class 10
|
||||||
|
config_get weight "$cfg" weight 10
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$srv" ] && [ -n "$target" ] && [ -n "$port" ] ; then
|
||||||
|
create_local_zone "$srv"
|
||||||
|
record="$srv.@@300@@IN@@SRV@@$class@@$weight@@$port@@$target."
|
||||||
|
DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
create_cname_record() {
|
||||||
|
local cfg="$1"
|
||||||
|
local cname target record
|
||||||
|
|
||||||
|
# Insert static CNAME record
|
||||||
|
config_get cname "$cfg" cname
|
||||||
|
config_get target "$cfg" target
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$cname" ] && [ -n "$target" ] ; then
|
||||||
|
create_local_zone "$cname"
|
||||||
|
record="$cname.@@300@@IN@@CNAME@@$target."
|
||||||
|
DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $record"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
dnsmasq_local_zone() {
|
dnsmasq_local_zone() {
|
||||||
local cfg="$1"
|
local cfg="$1"
|
||||||
local fwd_port fwd_domain wan_fqdn
|
local fwd_port fwd_domain wan_fqdn
|
||||||
@ -34,130 +168,129 @@ dnsmasq_local_zone() {
|
|||||||
|
|
||||||
|
|
||||||
if [ -n "$wan_fqdn" ] ; then
|
if [ -n "$wan_fqdn" ] ; then
|
||||||
UNBOUND_D_WAN_FQDN=$wan_fqdn
|
DM_D_WAN_FQDN=$wan_fqdn
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$fwd_domain" -a -n "$fwd_port" -a ! "${fwd_port:-53}" -eq 53 ] ; then
|
|
||||||
# dnsmasq localhost listening ports (possible multiple instances)
|
|
||||||
UNBOUND_N_FWD_PORTS="$UNBOUND_N_FWD_PORTS $fwd_port"
|
|
||||||
UNBOUND_TXT_FWD_ZONE="$UNBOUND_TXT_FWD_ZONE $fwd_domain"
|
|
||||||
|
|
||||||
{
|
if [ -n "$fwd_domain" ] && [ -n "$fwd_port" ] \
|
||||||
# This creates DOMAIN local privledges
|
&& [ ! "${fwd_port:-53}" -eq 53 ] ; then
|
||||||
echo " private-domain: \"$fwd_domain\""
|
# dnsmasq localhost listening ports (possible multiple instances)
|
||||||
echo " local-zone: \"$fwd_domain.\" transparent"
|
DM_LIST_FWD_PORTS="$DM_LIST_FWD_PORTS $fwd_port"
|
||||||
echo " domain-insecure: \"$fwd_domain\""
|
DM_LIST_FWD_ZONES="$DM_LIST_FWD_ZONES $fwd_domain"
|
||||||
echo
|
|
||||||
} >> $UNBOUND_CONFFILE
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
dnsmasq_local_arpa() {
|
dnsmasq_local_arpa() {
|
||||||
local cfg="$1"
|
local ifarpa ifsubnet
|
||||||
local logint dhcpv4 dhcpv6 ignore
|
|
||||||
local subnets subnets4 subnets6
|
|
||||||
local forward arpa
|
|
||||||
local validip4 validip6 privateip
|
|
||||||
|
|
||||||
config_get logint "$cfg" interface
|
|
||||||
config_get dhcpv4 "$cfg" dhcpv4
|
|
||||||
config_get dhcpv6 "$cfg" dhcpv6
|
|
||||||
config_get_bool ignore "$cfg" ignore 0
|
|
||||||
|
|
||||||
# Find the list of addresses assigned to a logical interface
|
|
||||||
# Its typical to have a logical gateway split NAME and NAME6
|
|
||||||
network_get_subnets subnets4 "$logint"
|
|
||||||
network_get_subnets6 subnets6 "$logint"
|
|
||||||
subnets="$subnets4 $subnets6"
|
|
||||||
|
|
||||||
network_get_subnets subnets4 "${logint}6"
|
|
||||||
network_get_subnets6 subnets6 "${logint}6"
|
|
||||||
subnets="$subnets $subnets4 $subnets6"
|
|
||||||
|
|
||||||
|
|
||||||
if [ -z "$subnets" ] ; then
|
if [ -n "$UB_LIST_NETW_LAN" ] ; then
|
||||||
forward=""
|
for ifsubnet in $UB_LIST_NETW_LAN ; do
|
||||||
|
ifarpa=$( domain_ptr_any "${ifsubnet#*@}" )
|
||||||
elif [ -z "$UNBOUND_N_FWD_PORTS" ] ; then
|
DM_LIST_FWD_ZONES="$DM_LIST_FWD_ZONES $ifarpa"
|
||||||
forward=""
|
done
|
||||||
|
|
||||||
elif [ "$ignore" -gt 0 ] ; then
|
|
||||||
if [ "$UNBOUND_D_WAN_FQDN" -gt 0 ] ; then
|
|
||||||
# Only forward the one gateway host.
|
|
||||||
forward="host"
|
|
||||||
|
|
||||||
else
|
|
||||||
forward=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
# Forward the entire private subnet.
|
|
||||||
forward="domain"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ -n "$forward" ] ; then
|
if [ -n "$UB_LIST_NETW_WAN" ] && [ "$DM_D_WAN_FQDN" -gt 0 ] ; then
|
||||||
for subnet in $subnets ; do
|
for ifsubnet in $UB_LIST_NETW_WAN ; do
|
||||||
validip4=$( valid_subnet4 $subnet )
|
ifarpa=$( domain_ptr_any "${ifsubnet#*@}" )
|
||||||
validip6=$( valid_subnet6 $subnet )
|
DM_LIST_FWD_ZONES="$DM_LIST_FWD_ZONES $ifarpa"
|
||||||
privateip=$( private_subnet $subnet )
|
|
||||||
|
|
||||||
|
|
||||||
if [ "$validip4" = "ok" -a "$dhcpv4" != "disable" ] ; then
|
|
||||||
if [ "$forward" = "domain" ] ; then
|
|
||||||
arpa=$( domain_ptr_ip4 "$subnet" )
|
|
||||||
else
|
|
||||||
arpa=$( host_ptr_ip4 "$subnet" )
|
|
||||||
fi
|
|
||||||
|
|
||||||
elif [ "$validip6" = "ok" -a "$dhcpv6" != "disable" ] ; then
|
|
||||||
if [ "$forward" = "domain" ] ; then
|
|
||||||
arpa=$( domain_ptr_ip6 "$subnet" )
|
|
||||||
else
|
|
||||||
arpa=$( host_ptr_ip6 "$subnet" )
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
arpa=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if [ -n "$arpa" ] ; then
|
|
||||||
if [ "$privateip" = "ok" ] ; then
|
|
||||||
{
|
|
||||||
# This creates ARPA local zone privledges
|
|
||||||
echo " local-zone: \"$arpa.\" transparent"
|
|
||||||
echo " domain-insecure: \"$arpa\""
|
|
||||||
echo
|
|
||||||
} >> $UNBOUND_CONFFILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
UNBOUND_TXT_FWD_ZONE="$UNBOUND_TXT_FWD_ZONE $arpa"
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
dnsmasq_forward_zone() {
|
dnsmasq_inactive() {
|
||||||
if [ -n "$UNBOUND_N_FWD_PORTS" -a -n "$UNBOUND_TXT_FWD_ZONE" ] ; then
|
local record
|
||||||
for fwd_domain in $UNBOUND_TXT_FWD_ZONE ; do
|
|
||||||
{
|
|
||||||
# This is derived of dnsmasq_local_zone/arpa
|
|
||||||
# but forward: clauses need to be seperate
|
|
||||||
echo "forward-zone:"
|
|
||||||
echo " name: \"$fwd_domain.\""
|
|
||||||
|
|
||||||
for port in $UNBOUND_N_FWD_PORTS ; do
|
|
||||||
|
if [ "$UB_D_EXTRA_DNS" -gt 0 ] ; then
|
||||||
|
# Parasite from the uci.dhcp.domain clauses
|
||||||
|
DM_LIST_KNOWN_ZONES="$DM_LIST_KNOWN_ZONES $UB_TXT_DOMAIN"
|
||||||
|
config_load dhcp
|
||||||
|
config_foreach create_host_record domain
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$UB_D_EXTRA_DNS" -gt 1 ] ; then
|
||||||
|
config_foreach create_srv_record srvhost
|
||||||
|
config_foreach create_mx_record mxhost
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$UB_D_EXTRA_DNS" -gt 2 ] ; then
|
||||||
|
config_foreach create_cname_record cname
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "# $UB_SRVMASQ_CONF generated by UCI $( date -Is )"
|
||||||
|
if [ -n "$DM_LIST_TRN_ZONES" ] ; then
|
||||||
|
for record in $DM_LIST_TRN_ZONES ; do
|
||||||
|
echo " local-zone: $record transparent"
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
if [ -n "$DM_LIST_LOCAL_DATA" ] ; then
|
||||||
|
for record in $DM_LIST_LOCAL_DATA ; do
|
||||||
|
echo " local-data: \"${record//@@/ }\""
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
if [ -n "$DM_LIST_LOCAL_PTR" ] ; then
|
||||||
|
for record in $DM_LIST_LOCAL_PTR ; do
|
||||||
|
echo " local-data-ptr: \"${record//@@/ }\""
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
} > $UB_SRVMASQ_CONF
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
dnsmasq_active() {
|
||||||
|
# Look at dnsmasq settings
|
||||||
|
config_load dhcp
|
||||||
|
# Zone for DHCP / SLAAC-PING DOMAIN
|
||||||
|
config_foreach dnsmasq_local_zone dnsmasq
|
||||||
|
# Zone for DHCP / SLAAC-PING ARPA
|
||||||
|
dnsmasq_local_arpa
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$DM_LIST_FWD_PORTS" ] && [ -n "$DM_LIST_FWD_ZONES" ] ; then
|
||||||
|
{
|
||||||
|
# Forward to dnsmasq on same host for DHCP lease hosts
|
||||||
|
echo "# $UB_SRVMASQ_CONF generated by UCI $( date -Is )"
|
||||||
|
echo " do-not-query-localhost: no"
|
||||||
|
echo
|
||||||
|
} > $UB_SRVMASQ_CONF
|
||||||
|
|
||||||
|
echo "# $UB_EXTMASQ_CONF generated by UCI $( date -Is )" > $UB_EXTMASQ_CONF
|
||||||
|
|
||||||
|
|
||||||
|
for fwd_domain in $DM_LIST_FWD_ZONES ; do
|
||||||
|
{
|
||||||
|
# This creates a domain with local privledges
|
||||||
|
echo " domain-insecure: $fwd_domain"
|
||||||
|
echo " private-domain: $fwd_domain"
|
||||||
|
echo " local-zone: $fwd_domain transparent"
|
||||||
|
echo
|
||||||
|
} >> $UB_SRVMASQ_CONF
|
||||||
|
|
||||||
|
{
|
||||||
|
# This is derived from dnsmasq local domain and dhcp service subnets
|
||||||
|
echo "forward-zone:"
|
||||||
|
echo " name: $fwd_domain"
|
||||||
|
echo " forward-first: no"
|
||||||
|
for port in $DM_LIST_FWD_PORTS ; do
|
||||||
echo " forward-addr: 127.0.0.1@$port"
|
echo " forward-addr: 127.0.0.1@$port"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo
|
echo
|
||||||
} >> $UNBOUND_CONFFILE
|
} >> $UB_EXTMASQ_CONF
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -165,16 +298,12 @@ dnsmasq_forward_zone() {
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
dnsmasq_link() {
|
dnsmasq_link() {
|
||||||
# Forward to dnsmasq on same host for DHCP lease hosts
|
if [ "$UB_D_DHCP_LINK" = "dnsmasq" ] ; then
|
||||||
echo " do-not-query-localhost: no" >> $UNBOUND_CONFFILE
|
dnsmasq_active
|
||||||
# Look at dnsmasq settings
|
|
||||||
config_load dhcp
|
else
|
||||||
# Zone for DHCP / SLAAC-PING DOMAIN
|
dnsmasq_inactive
|
||||||
config_foreach dnsmasq_local_zone dnsmasq
|
fi
|
||||||
# Zone for DHCP / SLAAC-PING ARPA
|
|
||||||
config_foreach dnsmasq_local_arpa dhcp
|
|
||||||
# Now create ALL seperate forward: clauses
|
|
||||||
dnsmasq_forward_zone
|
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
@ -124,6 +124,20 @@ valid_subnet4() {
|
|||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
valid_subnet_any() {
|
||||||
|
local subnet=$1
|
||||||
|
local validip4=$( valid_subnet4 $subnet )
|
||||||
|
local validip6=$( valid_subnet6 $subnet )
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$validip4" = "ok" ] || [ "$validip6" = "ok" ] ; then
|
||||||
|
echo "ok"
|
||||||
|
else
|
||||||
|
echo "not"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
private_subnet() {
|
private_subnet() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
10"."*) echo "ok" ;;
|
10"."*) echo "ok" ;;
|
||||||
@ -138,3 +152,47 @@ private_subnet() {
|
|||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
domain_ptr_any() {
|
||||||
|
local subnet=$1
|
||||||
|
local arpa validip4 validip6
|
||||||
|
|
||||||
|
validip4=$( valid_subnet4 $subnet )
|
||||||
|
validip6=$( valid_subnet6 $subnet )
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$validip4" = "ok" ] ; then
|
||||||
|
arpa=$( domain_ptr_ip4 "$subnet" )
|
||||||
|
elif [ "$validip6" = "ok" ] ; then
|
||||||
|
arpa=$( domain_ptr_ip6 "$subnet" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$arpa" ] ; then
|
||||||
|
echo $arpa
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
host_ptr_any() {
|
||||||
|
local subnet=$1
|
||||||
|
local arpa validip4 validip6
|
||||||
|
|
||||||
|
validip4=$( valid_subnet4 $subnet )
|
||||||
|
validip6=$( valid_subnet6 $subnet )
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$validip4" = "ok" ] ; then
|
||||||
|
arpa=$( host_ptr_ip4 "$subnet" )
|
||||||
|
elif [ "$validip6" = "ok" ] ; then
|
||||||
|
arpa=$( host_ptr_ip6 "$subnet" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$arpa" ] ; then
|
||||||
|
echo $arpa
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
@ -18,11 +18,12 @@
|
|||||||
# function from dnsmasq and use DHCPv4 MAC to find IPV6 SLAAC hosts.
|
# function from dnsmasq and use DHCPv4 MAC to find IPV6 SLAAC hosts.
|
||||||
#
|
#
|
||||||
# External Parameters
|
# External Parameters
|
||||||
# "hostfile" = where this script will cache host DNS data
|
# "conffile" = Unbound configuration left for a restart
|
||||||
|
# "pipefile" = DNS entries for unbound-control standard input
|
||||||
# "domain" = text domain suffix
|
# "domain" = text domain suffix
|
||||||
# "bslaac" = boolean, use DHCPv4 MAC to find GA and ULA IPV6 SLAAC
|
# "bslaac" = boolean, use DHCPv4 MAC to find GA and ULA IPV6 SLAAC
|
||||||
# "bisolt" = boolean, format <host>.<network>.<domain>. so you can isolate
|
# "bisolt" = boolean, format <host>.<network>.<domain>. so you can isolate
|
||||||
# "bconf" = boolean, write conf file format rather than pipe records
|
# "bconf" = boolean, write conf file with pipe records
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -35,10 +36,12 @@
|
|||||||
sub( /.*\//, "", cdr ) ;
|
sub( /.*\//, "", cdr ) ;
|
||||||
sub( /\/.*/, "", adr2 ) ;
|
sub( /\/.*/, "", adr2 ) ;
|
||||||
sub( /.*\//, "", cdr2 ) ;
|
sub( /.*\//, "", cdr2 ) ;
|
||||||
|
gsub( /_/, "-", hst ) ;
|
||||||
|
|
||||||
|
|
||||||
if ( hst !~ /^[[:alnum:]]([-[:alnum:]]*[[:alnum:]])?$/ ) {
|
if ( hst !~ /^[[:alnum:]]([-[:alnum:]]*[[:alnum:]])?$/ ) {
|
||||||
# that is not a valid host name (RFC1123)
|
# that is not a valid host name (RFC1123)
|
||||||
|
# above replaced common error of "_" in host name with "-"
|
||||||
hst = "-" ;
|
hst = "-" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +50,7 @@
|
|||||||
# TODO: this might be better with a substituion option,
|
# TODO: this might be better with a substituion option,
|
||||||
# or per DHCP pool do-not-DNS option, but its getting busy here.
|
# or per DHCP pool do-not-DNS option, but its getting busy here.
|
||||||
fqdn = net
|
fqdn = net
|
||||||
fqdn = sub( /\./, "-", fqdn ) ;
|
gsub( /\./, "-", fqdn ) ;
|
||||||
fqdn = tolower( hst "." fqdn "." domain ) ;
|
fqdn = tolower( hst "." fqdn "." domain ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,17 +67,17 @@
|
|||||||
|
|
||||||
|
|
||||||
if ( bconf == 1 ) {
|
if ( bconf == 1 ) {
|
||||||
x = ( "local-data: \"" fqdn ". 120 IN A " adr "\"" ) ;
|
x = ( "local-data: \"" fqdn ". 300 IN A " adr "\"" ) ;
|
||||||
y = ( "local-data-ptr: \"" adr " 120 " fqdn "\"" ) ;
|
y = ( "local-data-ptr: \"" adr " 300 " fqdn "\"" ) ;
|
||||||
print ( x "\n" y "\n" ) > hostfile ;
|
print ( x "\n" y "\n" ) > conffile ;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
|
||||||
for( i=1; i<=4; i++ ) { qpr = ( ptr[i] "." qpr) ; }
|
# always create the pipe file
|
||||||
x = ( fqdn ". 120 IN A " adr ) ;
|
for( i=1; i<=4; i++ ) { qpr = ( ptr[i] "." qpr) ; }
|
||||||
y = ( qpr "in-addr.arpa. 120 IN PTR " fqdn ) ;
|
x = ( fqdn ". 300 IN A " adr ) ;
|
||||||
print ( x "\n" y ) > hostfile ;
|
y = ( qpr "in-addr.arpa. 300 IN PTR " fqdn ) ;
|
||||||
}
|
print ( x "\n" y ) > pipefile ;
|
||||||
|
|
||||||
|
|
||||||
if (( bslaac == 1 ) && ( slaac != 0 )) {
|
if (( bslaac == 1 ) && ( slaac != 0 )) {
|
||||||
@ -85,6 +88,7 @@
|
|||||||
|
|
||||||
while ( ( cmd | getline adr ) > 0 ) {
|
while ( ( cmd | getline adr ) > 0 ) {
|
||||||
if (( substr( adr, 1, 5 ) <= "fdff:" ) \
|
if (( substr( adr, 1, 5 ) <= "fdff:" ) \
|
||||||
|
&& ( index( adr, "::/" ) != 0 ) \
|
||||||
&& ( index( adr, "anycast" ) == 0 ) \
|
&& ( index( adr, "anycast" ) == 0 ) \
|
||||||
&& ( index( adr, "via" ) == 0 )) {
|
&& ( index( adr, "via" ) == 0 )) {
|
||||||
# GA or ULA routed addresses only (not LL or MC)
|
# GA or ULA routed addresses only (not LL or MC)
|
||||||
@ -98,17 +102,17 @@
|
|||||||
|
|
||||||
|
|
||||||
if ( bconf == 1 ) {
|
if ( bconf == 1 ) {
|
||||||
x = ( "local-data: \"" fqdn ". 120 IN AAAA " adr "\"" ) ;
|
x = ( "local-data: \"" fqdn ". 300 IN AAAA " adr "\"" ) ;
|
||||||
y = ( "local-data-ptr: \"" adr " 120 " fqdn "\"" ) ;
|
y = ( "local-data-ptr: \"" adr " 300 " fqdn "\"" ) ;
|
||||||
print ( x "\n" y "\n" ) > hostfile ;
|
print ( x "\n" y "\n" ) > conffile ;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
|
||||||
qpr = ipv6_ptr( adr ) ;
|
# always create the pipe file
|
||||||
x = ( fqdn ". 120 IN AAAA " adr ) ;
|
qpr = ipv6_ptr( adr ) ;
|
||||||
y = ( qpr ". 120 IN PTR " fqdn ) ;
|
x = ( fqdn ". 300 IN AAAA " adr ) ;
|
||||||
print ( x "\n" y ) > hostfile ;
|
y = ( qpr ". 300 IN PTR " fqdn ) ;
|
||||||
}
|
print ( x "\n" y ) > pipefile ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,34 +124,32 @@
|
|||||||
else if ((cls != "ipv4") && (hst != "-") && (9 <= NF) && (NF <= 10)) {
|
else if ((cls != "ipv4") && (hst != "-") && (9 <= NF) && (NF <= 10)) {
|
||||||
if (cdr == 128) {
|
if (cdr == 128) {
|
||||||
if ( bconf == 1 ) {
|
if ( bconf == 1 ) {
|
||||||
x = ( "local-data: \"" fqdn ". 120 IN AAAA " adr "\"" ) ;
|
x = ( "local-data: \"" fqdn ". 300 IN AAAA " adr "\"" ) ;
|
||||||
y = ( "local-data-ptr: \"" adr " 120 " fqdn "\"" ) ;
|
y = ( "local-data-ptr: \"" adr " 300 " fqdn "\"" ) ;
|
||||||
print ( x "\n" y "\n" ) > hostfile ;
|
print ( x "\n" y "\n" ) > conffile ;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
|
||||||
# only for provided hostnames and full /128 assignments
|
# only for provided hostnames and full /128 assignments
|
||||||
qpr = ipv6_ptr( adr ) ;
|
qpr = ipv6_ptr( adr ) ;
|
||||||
x = ( fqdn ". 120 IN AAAA " adr ) ;
|
x = ( fqdn ". 300 IN AAAA " adr ) ;
|
||||||
y = ( qpr ". 120 IN PTR " fqdn ) ;
|
y = ( qpr ". 300 IN PTR " fqdn ) ;
|
||||||
print ( x "\n" y ) > hostfile ;
|
print ( x "\n" y ) > pipefile ;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdr2 == 128) {
|
if (cdr2 == 128) {
|
||||||
if ( bconf == 1 ) {
|
if ( bconf == 1 ) {
|
||||||
x = ( "local-data: \"" fqdn ". 120 IN AAAA " adr2 "\"" ) ;
|
x = ( "local-data: \"" fqdn ". 300 IN AAAA " adr2 "\"" ) ;
|
||||||
y = ( "local-data-ptr: \"" adr2 " 120 " fqdn "\"" ) ;
|
y = ( "local-data-ptr: \"" adr2 " 300 " fqdn "\"" ) ;
|
||||||
print ( x "\n" y "\n" ) > hostfile ;
|
print ( x "\n" y "\n" ) > conffile ;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
|
||||||
# odhcp puts GA and ULA on the same line (position 9 and 10)
|
# odhcp puts GA and ULA on the same line (position 9 and 10)
|
||||||
qpr2 = ipv6_ptr( adr2 ) ;
|
qpr2 = ipv6_ptr( adr2 ) ;
|
||||||
x = ( fqdn ". 120 IN AAAA " adr2 ) ;
|
x = ( fqdn ". 300 IN AAAA " adr2 ) ;
|
||||||
y = ( qpr2 ". 120 IN PTR " fqdn ) ;
|
y = ( qpr2 ". 300 IN PTR " fqdn ) ;
|
||||||
print ( x "\n" y ) > hostfile ;
|
print ( x "\n" y ) > pipefile ;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,82 +29,90 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
odhcpd_zonedata() {
|
odhcpd_zonedata() {
|
||||||
local longconf dateconf
|
|
||||||
local dns_ls_add=$UNBOUND_VARDIR/dhcp_dns.add
|
|
||||||
local dns_ls_del=$UNBOUND_VARDIR/dhcp_dns.del
|
|
||||||
local dhcp_ls_new=$UNBOUND_VARDIR/dhcp_lease.new
|
|
||||||
local dhcp_ls_old=$UNBOUND_VARDIR/dhcp_lease.old
|
|
||||||
local dhcp_ls_add=$UNBOUND_VARDIR/dhcp_lease.add
|
|
||||||
local dhcp_ls_del=$UNBOUND_VARDIR/dhcp_lease.del
|
|
||||||
|
|
||||||
local dhcp_link=$( uci_get unbound.@unbound[0].dhcp_link )
|
local dhcp_link=$( uci_get unbound.@unbound[0].dhcp_link )
|
||||||
local dhcp4_slaac6=$( uci_get unbound.@unbound[0].dhcp4_slaac6 )
|
local dhcp4_slaac6=$( uci_get unbound.@unbound[0].dhcp4_slaac6 )
|
||||||
local dhcp_domain=$( uci_get unbound.@unbound[0].domain )
|
local dhcp_domain=$( uci_get unbound.@unbound[0].domain )
|
||||||
local dhcp_origin=$( uci_get dhcp.@odhcpd[0].leasefile )
|
local dhcp_origin=$( uci_get dhcp.@odhcpd[0].leasefile )
|
||||||
|
|
||||||
|
|
||||||
if [ "$dhcp_link" = "odhcpd" -a -f "$dhcp_origin" ] ; then
|
if [ -f "$UB_TOTAL_CONF" ] && [ -f "$dhcp_origin" ] \
|
||||||
|
&& [ "$dhcp_link" = "odhcpd" ] && [ -n "$dhcp_domain" ] ; then
|
||||||
|
local longconf dateconf
|
||||||
|
local dns_ls_add=$UB_VARDIR/dhcp_dns.add
|
||||||
|
local dns_ls_del=$UB_VARDIR/dhcp_dns.del
|
||||||
|
local dns_ls_new=$UB_VARDIR/dhcp_dns.new
|
||||||
|
local dns_ls_old=$UB_VARDIR/dhcp_dns.old
|
||||||
|
local dhcp_ls_new=$UB_VARDIR/dhcp_lease.new
|
||||||
|
|
||||||
# Capture the lease file which could be changing often
|
# Capture the lease file which could be changing often
|
||||||
sort $dhcp_origin > $dhcp_ls_new
|
sort $dhcp_origin > $dhcp_ls_new
|
||||||
|
|
||||||
|
|
||||||
if [ ! -f $UNBOUND_DHCP_CONF -o ! -f $dhcp_ls_old ] ; then
|
if [ ! -f $UB_DHCP_CONF ] || [ ! -f $dns_ls_old ] ; then
|
||||||
longconf=2
|
# no old files laying around
|
||||||
|
longconf=freshstart
|
||||||
|
|
||||||
else
|
else
|
||||||
dateconf=$(( $( date +%s ) - $( date -r $UNBOUND_DHCP_CONF +%s ) ))
|
# incremental at high load or full refresh about each 5 minutes
|
||||||
|
dateconf=$(( $( date +%s ) - $( date -r $UB_DHCP_CONF +%s ) ))
|
||||||
|
|
||||||
|
|
||||||
if [ $dateconf > 150 ] ; then
|
if [ $dateconf -gt 300 ] ; then
|
||||||
longconf=1
|
longconf=longtime
|
||||||
else
|
else
|
||||||
longconf=0
|
longconf=increment
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ $longconf -gt 0 ] ; then
|
case $longconf in
|
||||||
# Go through the messy business of coding up A, AAAA, and PTR records
|
freshstart)
|
||||||
# This static conf will be available if Unbound restarts asynchronously
|
awk -v conffile=$UB_DHCP_CONF -v pipefile=$dns_ls_new \
|
||||||
awk -v hostfile=$UNBOUND_DHCP_CONF -v domain=$dhcp_domain \
|
-v domain=$dhcp_domain -v bslaac=$dhcp4_slaac6 \
|
||||||
-v bslaac=$dhcp4_slaac6 -v bisolt=0 -v bconf=1 \
|
-v bisolt=0 -v bconf=1 \
|
||||||
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_new
|
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_new
|
||||||
fi
|
|
||||||
|
|
||||||
|
cp $dns_ls_new $dns_ls_add
|
||||||
|
cp $dns_ls_new $dns_ls_old
|
||||||
|
;;
|
||||||
|
|
||||||
if [ $longconf -lt 2 ] ; then
|
longtime)
|
||||||
# Deleting and adding all records into Unbound can be a burden in a
|
awk -v conffile=$UB_DHCP_CONF -v pipefile=$dns_ls_new \
|
||||||
# high density environment. Use unbound-control incrementally.
|
-v domain=$dhcp_domain -v bslaac=$dhcp4_slaac6 \
|
||||||
sort $dhcp_ls_old $dhcp_ls_new $dhcp_ls_new | uniq -u > $dhcp_ls_del
|
-v bisolt=0 -v bconf=1 \
|
||||||
awk -v hostfile=$dns_ls_del -v domain=$dhcp_domain \
|
|
||||||
-v bslaac=$dhcp4_slaac6 -v bisolt=0 -v bconf=0 \
|
|
||||||
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_del
|
|
||||||
|
|
||||||
sort $dhcp_ls_new $dhcp_ls_old $dhcp_ls_old | uniq -u > $dhcp_ls_add
|
|
||||||
awk -v hostfile=$dns_ls_add -v domain=$dhcp_domain \
|
|
||||||
-v bslaac=$dhcp4_slaac6 -v bisolt=0 -v bconf=0 \
|
|
||||||
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_add
|
|
||||||
|
|
||||||
else
|
|
||||||
awk -v hostfile=$dns_ls_add -v domain=$dhcp_domain \
|
|
||||||
-v bslaac=$dhcp4_slaac6 -v bisolt=0 -v bconf=0 \
|
|
||||||
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_new
|
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_new
|
||||||
fi
|
|
||||||
|
awk '{ print $1 }' $dns_ls_old | sort | uniq > $dns_ls_del
|
||||||
|
cp $dns_ls_new $dns_ls_add
|
||||||
|
cp $dns_ls_new $dns_ls_old
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
# incremental add and prepare the old list for delete later
|
||||||
|
# unbound-control can be slow so high DHCP rates cannot run a full list
|
||||||
|
awk -v conffile=$UB_DHCP_CONF -v pipefile=$dns_ls_new \
|
||||||
|
-v domain=$dhcp_domain -v bslaac=$dhcp4_slaac6 \
|
||||||
|
-v bisolt=0 -v bconf=0 \
|
||||||
|
-f /usr/lib/unbound/odhcpd.awk $dhcp_ls_new
|
||||||
|
|
||||||
|
sort $dns_ls_new $dns_ls_old $dns_ls_old | uniq -u > $dns_ls_add
|
||||||
|
sort $dns_ls_new $dns_ls_old | uniq > $dns_ls_old
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
if [ -f "$dns_ls_del" ] ; then
|
if [ -f "$dns_ls_del" ] ; then
|
||||||
cat $dns_ls_del | $UNBOUND_CONTROL_CFG local_datas_remove
|
cat $dns_ls_del | $UB_CONTROL_CFG local_datas_remove
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ -f "$dns_ls_add" ] ; then
|
if [ -f "$dns_ls_add" ] ; then
|
||||||
cat $dns_ls_add | $UNBOUND_CONTROL_CFG local_datas
|
cat $dns_ls_add | $UB_CONTROL_CFG local_datas
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# prepare next round
|
# prepare next round
|
||||||
mv $dhcp_ls_new $dhcp_ls_old
|
rm -f $dns_ls_new $dns_ls_del $dns_ls_add $dhcp_ls_new
|
||||||
rm -f $dns_ls_del $dns_ls_add $dhcp_ls_del $dhcp_ls_add
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
. /usr/lib/unbound/defaults.sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
roothints_update() {
|
roothints_update() {
|
||||||
# TODO: Might not be implemented. Unbound doesn't natively update hints.
|
# TODO: Might not be implemented. Unbound doesn't natively update hints.
|
||||||
# Unbound philosophy is built in root hints are good for machine life.
|
# Unbound philosophy is built in root hints are good for machine life.
|
||||||
@ -29,17 +33,21 @@ roothints_update() {
|
|||||||
|
|
||||||
rootkey_update() {
|
rootkey_update() {
|
||||||
local basekey_date rootkey_date rootkey_age filestuff
|
local basekey_date rootkey_date rootkey_age filestuff
|
||||||
|
|
||||||
local dnssec=$( uci_get unbound.@unbound[0].validator )
|
local dnssec=$( uci_get unbound.@unbound[0].validator )
|
||||||
local dnssec_ntp=$( uci_get unbound.@unbound[0].validator_ntp )
|
local dnssec_ntp=$( uci_get unbound.@unbound[0].validator_ntp )
|
||||||
local dnssec_age=$( uci_get unbound.@unbound[0].root_age )
|
local dnssec_age=$( uci_get unbound.@unbound[0].root_age )
|
||||||
|
|
||||||
|
# fix empty
|
||||||
|
[ -z "$dnssec" ] && dnssec=0
|
||||||
|
[ -z "$dnssec_ntp" ] && dnssec_ntp=1
|
||||||
|
[ -z "$dnssec_age" ] && dnssec_age=9
|
||||||
|
|
||||||
if [ "$dnssec_age" -gt 90 -o "$dnssec" -lt 1 ] ; then
|
|
||||||
|
if [ "$dnssec_age" -gt 90 ] || [ "$dnssec" -lt 1 ] ; then
|
||||||
# Feature disabled
|
# Feature disabled
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
elif [ "$dnssec_ntp" -gt 0 -a ! -f "$UNBOUND_TIMEFILE" ] ; then
|
elif [ "$dnssec_ntp" -gt 0 ] && [ ! -f "$UB_TIME_FILE" ] ; then
|
||||||
# We don't have time yet
|
# We don't have time yet
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@ -54,16 +62,16 @@ rootkey_update() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ -f "$UNBOUND_KEYFILE" ] ; then
|
if [ -f "$UB_RKEY_FILE" ] ; then
|
||||||
# Unbound maintains it itself
|
# Unbound maintains it itself
|
||||||
rootkey_date=$( date -r $UNBOUND_KEYFILE +%s )
|
rootkey_date=$( date -r $UB_RKEY_FILE +%s )
|
||||||
rootkey_age=$(( (rootkey_date - basekey_date) / 86440 ))
|
rootkey_age=$(( (rootkey_date - basekey_date) / 86440 ))
|
||||||
|
|
||||||
elif [ -x "$UNBOUND_ANCHOR" ] ; then
|
elif [ -x "$UB_ANCHOR" ] ; then
|
||||||
# No tmpfs key - use unbound-anchor
|
# No tmpfs key - use unbound-anchor
|
||||||
rootkey_date=$( date -I +%s )
|
rootkey_date=$( date -I +%s )
|
||||||
rootkey_age=$(( (rootkey_date - basekey_date) / 86440 ))
|
rootkey_age=$(( (rootkey_date - basekey_date) / 86440 ))
|
||||||
$UNBOUND_ANCHOR -a $UNBOUND_KEYFILE
|
$UB_ANCHOR -a $UB_RKEY_FILE
|
||||||
|
|
||||||
else
|
else
|
||||||
# give up
|
# give up
|
||||||
@ -72,20 +80,20 @@ rootkey_update() {
|
|||||||
|
|
||||||
|
|
||||||
if [ "$rootkey_age" -gt "$dnssec_age" ] ; then
|
if [ "$rootkey_age" -gt "$dnssec_age" ] ; then
|
||||||
filestuff=$( cat $UNBOUND_KEYFILE )
|
filestuff=$( cat $UB_RKEY_FILE )
|
||||||
|
|
||||||
|
|
||||||
case "$filestuff" in
|
case "$filestuff" in
|
||||||
*NOERROR*)
|
*NOERROR*)
|
||||||
# Header comment for drill and dig
|
# Header comment for drill and dig
|
||||||
logger -t unbound -s "root.key updated after $rootkey_age days"
|
logger -t unbound -s "root.key updated after $rootkey_age days"
|
||||||
cp -p $UNBOUND_KEYFILE /etc/unbound/root.key
|
cp -p $UB_RKEY_FILE /etc/unbound/root.key
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*"state=2 [ VALID ]"*)
|
*"state=2 [ VALID ]"*)
|
||||||
# Comment inline to key for unbound-anchor
|
# Comment inline to key for unbound-anchor
|
||||||
logger -t unbound -s "root.key updated after $rootkey_age days"
|
logger -t unbound -s "root.key updated after $rootkey_age days"
|
||||||
cp -p $UNBOUND_KEYFILE /etc/unbound/root.key
|
cp -p $UB_RKEY_FILE /etc/unbound/root.key
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
@ -97,7 +105,20 @@ rootkey_update() {
|
|||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
rootzone_update() {
|
resolv_teardown() {
|
||||||
|
case $( cat /tmp/resolv.conf ) in
|
||||||
|
*"generated by Unbound UCI"*)
|
||||||
|
# our resolver file, reset to auto resolver file.
|
||||||
|
rm -f /tmp/resolv.conf
|
||||||
|
ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
unbound_stop() {
|
||||||
|
resolv_teardown
|
||||||
roothints_update
|
roothints_update
|
||||||
rootkey_update
|
rootkey_update
|
||||||
}
|
}
|
@ -17,14 +17,14 @@ PROG=/usr/sbin/unbound
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
boot() {
|
boot() {
|
||||||
UNBOUND_BOOT=1
|
UB_BOOT=1
|
||||||
start "$@"
|
start "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
start_service() {
|
start_service() {
|
||||||
if [ -n "$UNBOUND_BOOT" ] ; then
|
if [ -n "$UB_BOOT" ] ; then
|
||||||
# Load procd triggers (rc) and use event IFUP to really start
|
# Load procd triggers (rc) and use event IFUP to really start
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@ -35,7 +35,7 @@ start_service() {
|
|||||||
|
|
||||||
# standard procd clause
|
# standard procd clause
|
||||||
procd_open_instance "unbound"
|
procd_open_instance "unbound"
|
||||||
procd_set_param command $PROG -d -c $UNBOUND_CONFFILE
|
procd_set_param command $PROG -d -c $UB_TOTAL_CONF
|
||||||
procd_set_param respawn
|
procd_set_param respawn
|
||||||
procd_close_instance
|
procd_close_instance
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ start_service() {
|
|||||||
|
|
||||||
stop_service() {
|
stop_service() {
|
||||||
# clean up
|
# clean up
|
||||||
. /usr/lib/unbound/unbound.sh
|
. /usr/lib/unbound/stopping.sh
|
||||||
unbound_stop
|
unbound_stop
|
||||||
|
|
||||||
# Wait! on restart Unbound may take time writing closure stats to syslog
|
# Wait! on restart Unbound may take time writing closure stats to syslog
|
||||||
@ -54,22 +54,29 @@ stop_service() {
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
service_triggers() {
|
service_triggers() {
|
||||||
local trigger
|
|
||||||
local legacy=$( uci_get unbound.@unbound[0].trigger )
|
local legacy=$( uci_get unbound.@unbound[0].trigger )
|
||||||
local triggers=$( uci_get unbound.@unbound[0].trigger_interface )
|
local triggers=$( uci_get unbound.@unbound[0].trigger_interface )
|
||||||
|
local trigger="$triggers $legacy"
|
||||||
|
|
||||||
triggers="$triggers $legacy"
|
. /usr/lib/unbound/defaults.sh
|
||||||
PROCD_RELOAD_DELAY=2000
|
|
||||||
procd_add_reload_trigger "unbound"
|
|
||||||
|
if [ ! -f "$UB_TOTAL_CONF" ] || [ -n "$UB_BOOT" ] ; then
|
||||||
|
# Unbound can be a bit heavy, so wait some on first start. Any interface
|
||||||
|
# up affects the trigger delay and will guarantee start.
|
||||||
|
procd_add_raw_trigger "interface.*.up" 3000 /etc/init.d/unbound restart
|
||||||
|
|
||||||
|
elif [ -n "$triggers" ] ; then
|
||||||
|
procd_add_reload_trigger "unbound" "dhcp"
|
||||||
|
|
||||||
|
|
||||||
if [ -n "$triggers" ] ; then
|
|
||||||
for trigger in $triggers ; do
|
for trigger in $triggers ; do
|
||||||
# due to some netifd/procd interactions with IP6, limit interfaces
|
# User selected triggers to restart at any other time
|
||||||
procd_add_reload_interface_trigger "$trigger"
|
procd_add_reload_interface_trigger "$trigger"
|
||||||
done
|
done
|
||||||
|
|
||||||
else
|
else
|
||||||
procd_add_raw_trigger "interface.*.up" 2000 /etc/init.d/unbound reload
|
procd_add_reload_trigger "unbound" "dhcp"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Common file location definitions
|
# Common file location definitions
|
||||||
. /usr/lib/unbound/unbound.sh
|
. /usr/lib/unbound/defaults.sh
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
if [ "$ACTION" = stratum -a ! -f "$UNBOUND_TIMEFILE" ] ; then
|
if [ ! -f "$UB_TIME_FILE" -a "$ACTION" = stratum ] ; then
|
||||||
echo "ntpd: $( date )" > $UNBOUND_TIMEFILE
|
date -Is > $UB_TIME_FILE
|
||||||
/etc/init.d/unbound enabled && /etc/init.d/unbound restart
|
/etc/init.d/unbound enabled && /etc/init.d/unbound restart
|
||||||
# Yes, hard RESTART. We need to be absolutely sure to enable DNSSEC.
|
# Yes, hard RESTART. We need to be absolutely sure to enable DNSSEC.
|
||||||
fi
|
fi
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,12 +9,12 @@ config unbound
|
|||||||
option domain 'lan'
|
option domain 'lan'
|
||||||
option domain_type 'static'
|
option domain_type 'static'
|
||||||
option edns_size '1280'
|
option edns_size '1280'
|
||||||
option extended_luci '0'
|
|
||||||
option extended_stats '0'
|
option extended_stats '0'
|
||||||
option hide_binddata '1'
|
option hide_binddata '1'
|
||||||
option listen_port '53'
|
option listen_port '53'
|
||||||
option localservice '1'
|
option localservice '1'
|
||||||
option manual_conf '0'
|
option manual_conf '0'
|
||||||
|
option num_threads '1'
|
||||||
option protocol 'default'
|
option protocol 'default'
|
||||||
option query_minimize '0'
|
option query_minimize '0'
|
||||||
option query_min_strict '0'
|
option query_min_strict '0'
|
||||||
@ -27,9 +27,28 @@ config unbound
|
|||||||
option unbound_control '0'
|
option unbound_control '0'
|
||||||
option validator '0'
|
option validator '0'
|
||||||
option validator_ntp '1'
|
option validator_ntp '1'
|
||||||
|
option verbosity '1'
|
||||||
list trigger_interface 'lan'
|
list trigger_interface 'lan'
|
||||||
list trigger_interface 'wan'
|
list trigger_interface 'wan'
|
||||||
#list rebind_interface 'lan'
|
|
||||||
#list domain_insecure 'ntp.example.com'
|
#list domain_insecure 'ntp.example.com'
|
||||||
#list domain_forward 'mail.example.com'
|
|
||||||
|
config zone
|
||||||
|
option enabled '0'
|
||||||
|
option fallback '1'
|
||||||
|
option url_dir 'https://www.internic.net/domain/'
|
||||||
|
option zone_type 'auth_zone'
|
||||||
|
list server 'lax.xfr.dns.icann.org'
|
||||||
|
list server 'iad.xfr.dns.icann.org'
|
||||||
|
list zone_name '.'
|
||||||
|
list zone_name 'arpa.'
|
||||||
|
list zone_name 'in-addr.arpa.'
|
||||||
|
list zone_name 'ip6.arpa.'
|
||||||
|
|
||||||
|
config zone
|
||||||
|
option enabled '0'
|
||||||
|
option fallback '1'
|
||||||
|
option resolv_conf '1'
|
||||||
|
option zone_type 'forward_zone'
|
||||||
|
list zone_name 'isp-bill.example.com.'
|
||||||
|
list zone_name 'isp-mail.example.net.'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user