Initial commit
This commit is contained in:
108
roles/dhcp/README.md
Normal file
108
roles/dhcp/README.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# `flyoverhead.openwrt.dhcp`
|
||||
|
||||
OpenWRT `dhcp` configuration
|
||||
- configure dnsmasq settings
|
||||
- create/delete/configure dhcp pools
|
||||
- create/delete/configure static leases
|
||||
- create/delete/configure ipsets
|
||||
|
||||
## Role Variables
|
||||
|
||||
| Variable | Descritpion | Status | Type | Example |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| `dhcp_common` | DHCP and DNS [common options](https://openwrt.org/docs/guide-user/base-system/dhcp#common_options) | | `dictionary` | |
|
||||
|  `authoritative` | Force dnsmasq into authoritative mode (used if this is the only server on the network) | `required` | `boolean` | `1` |
|
||||
|  `boguspriv` | Reject reverse lookups to private IP ranges where no corresponding entry exists in `/etc/hosts` | `optional` | `boolean` | `1` |
|
||||
|  `cachesize` | Size of dnsmasq query cache | `optional` | `integer` | `150` |
|
||||
|  `domain` | Local domain suffix appended to DHCP names and hosts file entries | `optional` | `string` | `lan` |
|
||||
|  `domainneeded` | Never forward queries for plain names, without dots or domain parts, to upstream nameservers | `optional` | `boolean` | `1` |
|
||||
|  `dnssec` | Validate DNS replies and cache DNSSEC data | `optional` | `boolean` | `0` |
|
||||
|  `dnsseccheckunsigned` | Check the zones of unsigned replies to ensure that unsigned replies are allowed in those zones | `optional` | `boolean` | `0` |
|
||||
|  `expandhosts` | Add the local domain part to names found in /etc/hosts | `optional` | `boolean` | `1` |
|
||||
|  `filterwin2k` | Do not forward requests that cannot be answered by public name servers | `optional` | `boolean` | `0` |
|
||||
|  `fqdn` | Do not resolve unqualifed local hostnames (needs `domain` to be set) | `optional` | `boolean` | `0` |
|
||||
|  `leasefile` | Path to file to store DHCP leases in | `optional` | `string` | `/tmp/dhcp.leases` |
|
||||
|  `local` | Never forward matching domains and subdomains, resolve from DHCP or hosts files only. | `optional` | `string` | `/lan/` |
|
||||
|  `localise_queries` | Return answers to DNS queries matching the subnet from which the query was received if multiple IPs are available | `optional` | `boolean` | `1` |
|
||||
|  `localservice` | Accept DNS queries only from hosts whose address is on a local subnet | `optional` | `boolean` | `0` |
|
||||
|  `nonegcache` | Do not cache negative replies, e.g. for non-existent domains | `optional` | `boolean` | `1` |
|
||||
|  `nonwildcard` | Bind dynamically to interfaces rather than wildcard address | `optional` | `boolean` | `1` |
|
||||
|  `readethers` | Read static lease entries from /etc/ethers | `optional` | `boolean` | `1` |
|
||||
|  `rebind_protection` | Enables DNS rebind attack protection by discarding upstream RFC1918 responses | `optional` | `boolean` | `1` |
|
||||
|  `rebind_localhost` | Allows upstream 127.0.0.0/8 responses, required for DNS based blacklist services (needs `rebind_protection` to be enabled) | `optional` | `boolean` | `1` |
|
||||
|  `rebind_domain` | List of domains to allow RFC1918 responses for (needs `rebind_protection` to be enabled) | `optional` | `list` | `["/example.com/", "/maydomain.com/"]` |
|
||||
|  `resolvfile` | Path to file with upstream resolvers | `optional` | `string` | `"/tmp/resolv.conf.d/resolv.conf.auto` |
|
||||
|  `server` | List of DNS upstream servers to forward requests to | `optional` | `list` | `["192.168.1.1", "192.168.1.2"]` |
|
||||
|  `serverlist` | Path to file with DNS upstream servers list content | `optional` | `string` | `/etc/dnsmasq.servers` |
|
||||
|  `address` | List of IP addresses for queried domains | `optional` | `list` | `/site.example.com/192.168.1.1` |
|
||||
|  `allservers` | Force dnsmasq to send all queries to all available upstream DNS servers | `optional` | `boolean` | `0` |
|
||||
| `dhcp_pools` | List of per interface [lease pools and settings](https://openwrt.org/docs/guide-user/base-system/dhcp#dhcp_pools) | | `list of dictionaries` | |
|
||||
|  `id` | Unique dhcp pool ID | `mandatory` | `string` | `lan` |
|
||||
|  `interface` | Interface associated with DHCP pool (must be one of the interfaces defined in `/etc/config/network`) | `mandatory` | `string` | `lan` |
|
||||
|  `state` | DHCP pool status (`present` or `absent`) | `required` | `string` | `present` |
|
||||
|  `dhcp_option` | List of DHCP options | `optional` | `list` | `["3,192.168.1.1", "6,192.168.1.1"]` |
|
||||
|  `force` | Force DHCP serving on the specified interface even if another DHCP server is detected on the same network segment | `optional` | `boolean` | `0` |
|
||||
|  `dhcpv4` | Enable or disable DHCPv4 server (`server` or `disabled`) | `mandatory` | `string` | `server` |
|
||||
|  `leasetime` | Lease time of addresses handed out to client | `required` | `string` | `12h` |
|
||||
|  `limit` | Size of the address pool | `required` | `integer` | `150` |
|
||||
|  `start` | Offset from the network address of the underlying interface (for calculating the minimum address that may be leased to clients) | `required` | `integer` | `100` |
|
||||
|  `ra` | Operation mode of the Router Advertisements service (`server`, `relay`, `hybrid` or `disabled`) | `optional` | `string` | `disabled` |
|
||||
|  `dhcpv6` | Operation mode of the DHCPv6 service (`server`, `relay`, `hybrid` or `disabled`) | `optional` | `string` | `disabled` |
|
||||
|  `dns_service` | Enable local IPv6 DNS server | `optional` | `boolean` | `0` |
|
||||
| `dhcp_leases` | List of hosts' [static leases](https://openwrt.org/docs/guide-user/base-system/dhcp#static_leases) | | `list of dictionaries` | |
|
||||
|  `id` | Unique dhcp lease ID | `optional` | `string` | `host01` |
|
||||
|  `name` | Optional hostname to assign to the host | `optional` | `string` | `host01` |
|
||||
|  `state` | Static lease status (`present` or `absent`) | `required` | `string` | `present` |
|
||||
|  `ip` | IP address to assign to the host (`IP address` or `ignore`) | `mandatory` | `string` | `192.168.1.11` |
|
||||
|  `mac` | Hardware address of the host | `mandatory` | `string` | `00:11:22:33:44:55` |
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Name | Description |
|
||||
| :--- | :--- |
|
||||
| `Ansible Role: openwrt` | [Ansible role by gekmihesg](https://github.com/gekmihesg/ansible-openwrt) for managing OpenWRT and derivatives |
|
||||
|
||||
## Example Playbook
|
||||
|
||||
```yaml
|
||||
- hosts: openwrt
|
||||
roles:
|
||||
- role: flyoverhead.openwrt.dhcp
|
||||
```
|
||||
|
||||
## Example Vars
|
||||
|
||||
```yaml
|
||||
dhcp_common:
|
||||
authoritative: "1"
|
||||
boguspriv: "1"
|
||||
cachesize: "1000"
|
||||
domainneeded: "1"
|
||||
rebind_protection: "1"
|
||||
rebind_localhost: "1"
|
||||
dhcp_pools:
|
||||
- id: "lan"
|
||||
interface: "lan"
|
||||
state: "state"
|
||||
dhcpv4: "server"
|
||||
limit: "50"
|
||||
start: "50"
|
||||
dhcp_leases:
|
||||
- id: "host01"
|
||||
name: "host01"
|
||||
state: "present"
|
||||
ip: "192.168.1.51"
|
||||
mac: "00:11:22:33:44:55"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
## Author Information
|
||||
|
||||
fly0v3rH34D
|
||||
|
||||
## References
|
||||
|
||||
- https://openwrt.org/docs/guide-user/base-system/dhcp
|
||||
51
roles/dhcp/defaults/main.yml
Normal file
51
roles/dhcp/defaults/main.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
# dnsmasq section
|
||||
dhcp_common:
|
||||
authoritative: ""
|
||||
boguspriv: ""
|
||||
cachesize: ""
|
||||
domain: ""
|
||||
domainneeded: ""
|
||||
dnssec: ""
|
||||
dnsseccheckunsigned: ""
|
||||
expandhosts: ""
|
||||
filterwin2k: ""
|
||||
fqdn: ""
|
||||
leasefile: ""
|
||||
local: ""
|
||||
localise_queries: ""
|
||||
localservice: ""
|
||||
nonegcache: ""
|
||||
nonwildcard: ""
|
||||
readethers: ""
|
||||
rebind_protection: ""
|
||||
rebind_localhost: ""
|
||||
rebind_domain: []
|
||||
resolvfile: ""
|
||||
server: []
|
||||
serverlist: ""
|
||||
address: []
|
||||
allservers: ""
|
||||
|
||||
# dhcp section
|
||||
dhcp_pools:
|
||||
- id: ""
|
||||
interface: ""
|
||||
state: ""
|
||||
dhcp_option: []
|
||||
force: ""
|
||||
dhcpv4: ""
|
||||
leasetime: ""
|
||||
limit: ""
|
||||
start: ""
|
||||
ra: ""
|
||||
dhcpv6: ""
|
||||
dns_service: ""
|
||||
|
||||
# host section
|
||||
dhcp_leases:
|
||||
- id: ""
|
||||
name: ""
|
||||
state: ""
|
||||
ip: ""
|
||||
mac: ""
|
||||
7
roles/dhcp/handlers/main.yml
Normal file
7
roles/dhcp/handlers/main.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# Reload dhcp service
|
||||
- name: Reload dhcp
|
||||
ansible.builtin.service:
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
loop: ["dnsmasq", "odhcpd"]
|
||||
12
roles/dhcp/meta/main.yml
Normal file
12
roles/dhcp/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: flyoverhead
|
||||
description: Configure dhcp settings
|
||||
license: GPL-3.0
|
||||
min_ansible_version: "2.13"
|
||||
platforms:
|
||||
- name: OpenWrt
|
||||
versions: ["22.03"]
|
||||
galaxy_tags: ["openwrt", "dhcp"]
|
||||
dependencies:
|
||||
- role: gekmihesg.openwrt
|
||||
45
roles/dhcp/tasks/dhcp.yml
Normal file
45
roles/dhcp/tasks/dhcp.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
# Set state status for dhcp pool
|
||||
- name: Set state status for dhcp pool {{ item.id | default(item.interface) }}
|
||||
ansible.builtin.set_fact:
|
||||
dhcp_state: "{{ item.state | default('present') }}"
|
||||
|
||||
# Delete dhcp pool for interface
|
||||
- name: Delete dhcp pool for interface {{ item.id | default(item.interface) }}
|
||||
when: "'absent' in dhcp_state"
|
||||
uci:
|
||||
command: "absent"
|
||||
config: "dhcp"
|
||||
section: "{{ item.id | default(item.interface) }}"
|
||||
type: "dhcp"
|
||||
|
||||
# Create and configure dhcp pool for interface
|
||||
- name: Create and configure dhcp pool for interface
|
||||
when: "'present' in dhcp_state"
|
||||
block:
|
||||
# Create dhcp pool for interface
|
||||
- name: Create dhcp pool for interface {{ item.id | default(item.interface) }}
|
||||
uci:
|
||||
command: "add"
|
||||
config: "dhcp"
|
||||
section: "{{ item.id | default(item.interface) }}"
|
||||
type: "dhcp"
|
||||
|
||||
# Configure dhcp pool
|
||||
- name: Configure dhcp pool for {{ item.id | default(item.interface) }}
|
||||
uci:
|
||||
command: "set"
|
||||
config: "dhcp"
|
||||
section: "{{ item.id | default(item.interface) }}"
|
||||
type: "dhcp"
|
||||
value:
|
||||
interface: "{{ item.interface | default(omit) }}"
|
||||
dhcp_option: "{{ item.dhcp_option | default([]) | join(' ') }}"
|
||||
force: "{{ item.force | default(omit) }}"
|
||||
dhcpv4: "{{ item.dhcpv4 | default(omit) }}"
|
||||
leasetime: "{{ item.leasetime | default(omit) }}"
|
||||
limit: "{{ item.limit | default(omit) }}"
|
||||
start: "{{ item.start | default(omit) }}"
|
||||
ra: "{{ item.ra | default(omit) }}"
|
||||
dhcpv6: "{{ item.dhcpv6 | default(omit) }}"
|
||||
dns_service: "{{ item.dns_service | default(omit) }}"
|
||||
34
roles/dhcp/tasks/dnsmasq.yml
Normal file
34
roles/dhcp/tasks/dnsmasq.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Configure common options
|
||||
- name: Configure common options
|
||||
uci:
|
||||
command: "set"
|
||||
config: "dhcp"
|
||||
section: "@dnsmasq[0]"
|
||||
type: "dnsmasq"
|
||||
value:
|
||||
authoritative: "{{ dhcp_common.authoritative | default(omit) }}"
|
||||
boguspriv: "{{ dhcp_common.boguspriv | default(omit) }}"
|
||||
cachesize: "{{ dhcp_common.cachesize | default(omit) }}"
|
||||
domain: "{{ dhcp_common.domain | default(omit) }}"
|
||||
domainneeded: "{{ dhcp_common.domainneeded | default(omit) }}"
|
||||
dnssec: "{{ dhcp_common.dnssec | default(omit) }}"
|
||||
dnsseccheckunsigned: "{{ dhcp_common.dnsseccheckunsigned | default(omit) }}"
|
||||
expandhosts: "{{ dhcp_common.expandhosts | default(omit) }}"
|
||||
filterwin2k: "{{ dhcp_common.filterwin2k | default(omit) }}"
|
||||
fqdn: "{{ dhcp_common.fqdn | default(omit) }}"
|
||||
leasefile: "{{ dhcp_common.leasefile | default(omit) }}"
|
||||
local: "{{ dhcp_common.local | default(omit) }}"
|
||||
localise_queries: "{{ dhcp_common.localise_queries | default(omit) }}"
|
||||
localservice: "{{ dhcp_common.localservice | default(omit) }}"
|
||||
nonegcache: "{{ dhcp_common.nonegcache | default(omit) }}"
|
||||
nonwildcard: "{{ dhcp_common.nonwildcard | default(omit) }}"
|
||||
readethers: "{{ dhcp_common.readethers | default(omit) }}"
|
||||
rebind_protection: "{{ dhcp_common.rebind_protection | default(omit) }}"
|
||||
rebind_localhost: "{{ dhcp_common.rebind_localhost | default(omit) }}"
|
||||
rebind_domain: "{{ dhcp_common.rebind_domain | default([]) | join(' ') }}"
|
||||
resolvfile: "{{ dhcp_common.resolvfile | default([]) | join(' ') }}"
|
||||
server: "{{ dhcp_common.server | default([]) | join(' ') }}"
|
||||
serverlist: "{{ dhcp_common.serverlist | default(omit) }}"
|
||||
address: "{{ dhcp_common.address | default([]) | join(' ') }}"
|
||||
allservers: "{{ dhcp_common.allservers | default(omit) }}"
|
||||
40
roles/dhcp/tasks/host.yml
Normal file
40
roles/dhcp/tasks/host.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# Set static lease state status for host
|
||||
- name: Set static lease state status for host {{ item.id }}
|
||||
ansible.builtin.set_fact:
|
||||
static_lease_state: "{{ item.state | default('present') }}"
|
||||
|
||||
# Delete static lease for host
|
||||
- name: Delete static lease for host {{ item.id }}
|
||||
when: "'absent' in static_lease_state"
|
||||
uci:
|
||||
command: "absent"
|
||||
config: "dhcp"
|
||||
section: "{{ item.id }}"
|
||||
type: "host"
|
||||
|
||||
# Create and configure static lease for host
|
||||
- name: Create and configure static lease for host
|
||||
when: "'present' in static_lease_state"
|
||||
block:
|
||||
# Create static lease for host
|
||||
- name: Create static lease for host {{ item.id }}
|
||||
uci:
|
||||
command: "add"
|
||||
config: "dhcp"
|
||||
section: "{{ item.id | default('@host[-1]') }}"
|
||||
type: "host"
|
||||
|
||||
# Configure static lease for host
|
||||
- name: Configure static lease for host {{ item.id }}
|
||||
uci:
|
||||
command: "set"
|
||||
config: "dhcp"
|
||||
section: "{{ item.id | default('@host[-1]') }}"
|
||||
type: "host"
|
||||
value:
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
ip: "{{ item.ip | default(omit) }}"
|
||||
mac: "{{ item.mac | default(omit) }}"
|
||||
tag: "{{ item.tag | default(omit) }}"
|
||||
dns: "{{ item.dns | default(omit) }}"
|
||||
20
roles/dhcp/tasks/main.yml
Normal file
20
roles/dhcp/tasks/main.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# Configure dnsmasq section
|
||||
- name: Configure dnsmasq section
|
||||
ansible.builtin.include_tasks: dnsmasq.yml
|
||||
|
||||
# Configure dhcp section
|
||||
- name: Configure dhcp section
|
||||
ansible.builtin.include_tasks: dhcp.yml
|
||||
loop: "{{ dhcp_pools | default([]) }}"
|
||||
|
||||
# Configure host section
|
||||
- name: Configure host section
|
||||
ansible.builtin.include_tasks: host.yml
|
||||
loop: "{{ dhcp_leases | default([]) }}"
|
||||
|
||||
# Apply changes and reload DHCP service
|
||||
- name: Apply changes and reload dhcp
|
||||
uci:
|
||||
command: commit
|
||||
notify: Reload dhcp
|
||||
Reference in New Issue
Block a user