oxidized 0.29.1 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.coderabbit.yaml +21 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +45 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- data/.github/ISSUE_TEMPLATE/support-request.md +39 -0
- data/.github/workflows/codeql.yml +4 -4
- data/.github/workflows/publishdocker.yml +108 -13
- data/.github/workflows/ruby.yml +3 -12
- data/.github/workflows/stale.yml +6 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +69 -13
- data/.rubocop_todo.yml +13 -143
- data/CHANGELOG.md +431 -4
- data/CONTRIBUTING.md +189 -0
- data/Dockerfile +89 -34
- data/README.md +59 -188
- data/Rakefile +58 -12
- data/bin/oxidized +2 -5
- data/docs/Configuration.md +382 -149
- data/docs/Creating-Models.md +262 -10
- data/docs/DeviceSimulation.md +196 -0
- data/docs/Docker.md +246 -0
- data/docs/Hooks.md +146 -51
- data/docs/Inputs.md +237 -0
- data/docs/Issues.md +123 -0
- data/docs/Model-Notes/APC.md +72 -0
- data/docs/Model-Notes/Cumulus.md +5 -0
- data/docs/Model-Notes/EatonNetwork.md +18 -0
- data/docs/Model-Notes/ExaLink.md +43 -0
- data/docs/Model-Notes/FSOS.md +17 -0
- data/docs/Model-Notes/Fortinet.md +75 -0
- data/docs/Model-Notes/GrandstreamHT8xx.md +8 -0
- data/docs/Model-Notes/HPEAruba.md +32 -0
- data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
- data/docs/Model-Notes/OS6.md +10 -0
- data/docs/Model-Notes/README.md +1 -20
- data/docs/Model-Notes/RouterOS.md +28 -0
- data/docs/Model-Notes/SikluMHTG.md +7 -0
- data/docs/Model-Notes/TrueNAS.md +23 -0
- data/docs/Model-Notes/XGS4600-Zyxel.md +5 -0
- data/docs/ModelUnitTests.md +219 -0
- data/docs/Outputs.md +102 -5
- data/docs/Release.md +102 -0
- data/docs/Ruby-API.md +135 -2
- data/docs/Sources.md +34 -0
- data/docs/Supported-OS-Types.md +207 -270
- data/docs/Troubleshooting.md +43 -1
- data/extra/device2yaml.rb +259 -0
- data/extra/gitdiff-msteams.sh +32 -5
- data/extra/hooks/modelrules.rb +55 -0
- data/extra/hooks/modelrulesadvanced.rb +167 -0
- data/extra/hooks/srcipmap.rb +54 -0
- data/extra/nagios_check_failing_nodes.rb +1 -1
- data/extra/oxidized.runit +1 -1
- data/extra/rest_client.rb +5 -4
- data/extra/syslog.rb +11 -6
- data/lib/oxidized/cli/support.rb +152 -0
- data/lib/oxidized/cli.rb +21 -6
- data/lib/oxidized/config/vars.rb +33 -14
- data/lib/oxidized/config.rb +28 -17
- data/lib/oxidized/core.rb +50 -8
- data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
- data/lib/oxidized/hook/exec.rb +5 -4
- data/lib/oxidized/hook/githubrepo.rb +55 -18
- data/lib/oxidized/hook/noophook.rb +2 -2
- data/lib/oxidized/hook/slackdiff.rb +50 -14
- data/lib/oxidized/hook/xmppdiff.rb +9 -9
- data/lib/oxidized/hook.rb +68 -16
- data/lib/oxidized/input/cli.rb +8 -3
- data/lib/oxidized/input/debugtext.rb +40 -0
- data/lib/oxidized/input/debugyaml.rb +82 -0
- data/lib/oxidized/input/exec.rb +2 -11
- data/lib/oxidized/input/ftp.rb +2 -19
- data/lib/oxidized/input/http.rb +67 -17
- data/lib/oxidized/input/input.rb +35 -14
- data/lib/oxidized/input/scp.rb +27 -0
- data/lib/oxidized/input/ssh.rb +59 -83
- data/lib/oxidized/input/sshbase.rb +102 -0
- data/lib/oxidized/input/telnet.rb +20 -19
- data/lib/oxidized/input/tftp.rb +8 -8
- data/lib/oxidized/job.rb +18 -7
- data/lib/oxidized/jobs.rb +11 -1
- data/lib/oxidized/logger.rb +51 -0
- data/lib/oxidized/manager.rb +18 -17
- data/lib/oxidized/model/acos.rb +2 -1
- data/lib/oxidized/model/addpack.rb +26 -0
- data/lib/oxidized/model/adtran.rb +5 -1
- data/lib/oxidized/model/adva.rb +3 -3
- data/lib/oxidized/model/airfiber.rb +1 -1
- data/lib/oxidized/model/aos7.rb +11 -0
- data/lib/oxidized/model/aoscx.rb +37 -29
- data/lib/oxidized/model/aosw.rb +39 -29
- data/lib/oxidized/model/apc_aos.rb +7 -2
- data/lib/oxidized/model/apcaos.rb +39 -0
- data/lib/oxidized/model/aricentiss.rb +9 -2
- data/lib/oxidized/model/arubainstant.rb +93 -0
- data/lib/oxidized/model/asa.rb +11 -10
- data/lib/oxidized/model/asternos.rb +22 -0
- data/lib/oxidized/model/asyncos.rb +3 -3
- data/lib/oxidized/model/audiocodes.rb +2 -2
- data/lib/oxidized/model/awplus.rb +15 -12
- data/lib/oxidized/model/axos.rb +1 -1
- data/lib/oxidized/model/bdcom.rb +1 -0
- data/lib/oxidized/model/c4cmts.rb +1 -2
- data/lib/oxidized/model/ciscosma.rb +1 -1
- data/lib/oxidized/model/ciscosmb.rb +6 -1
- data/lib/oxidized/model/cnos.rb +13 -10
- data/lib/oxidized/model/comtrol.rb +1 -1
- data/lib/oxidized/model/comware.rb +5 -3
- data/lib/oxidized/model/cumulus.rb +14 -2
- data/lib/oxidized/model/defacto.rb +26 -0
- data/lib/oxidized/model/dellx.rb +1 -1
- data/lib/oxidized/model/dlink.rb +5 -2
- data/lib/oxidized/model/dlinknextgen.rb +55 -0
- data/lib/oxidized/model/dnos.rb +3 -0
- data/lib/oxidized/model/dslcommands.rb +93 -0
- data/lib/oxidized/model/dslsetup.rb +102 -0
- data/lib/oxidized/model/eatonnetwork.rb +70 -0
- data/lib/oxidized/model/edgecos.rb +3 -1
- data/lib/oxidized/model/edgeos.rb +7 -6
- data/lib/oxidized/model/edgeswitch.rb +3 -1
- data/lib/oxidized/model/efos.rb +41 -0
- data/lib/oxidized/model/eltex.rb +4 -2
- data/lib/oxidized/model/enterasys800.rb +2 -2
- data/lib/oxidized/model/enterprise_sonic.rb +46 -0
- data/lib/oxidized/model/eos.rb +3 -1
- data/lib/oxidized/model/exalink.rb +36 -0
- data/lib/oxidized/model/f5os.rb +17 -0
- data/lib/oxidized/model/fabricos.rb +2 -2
- data/lib/oxidized/model/fastiron.rb +5 -3
- data/lib/oxidized/model/firebrick.rb +2 -2
- data/lib/oxidized/model/firelinuxos.rb +13 -6
- data/lib/oxidized/model/firewareos.rb +10 -1
- data/lib/oxidized/model/fortigate.rb +160 -0
- data/lib/oxidized/model/fortios.rb +38 -48
- data/lib/oxidized/model/fsos.rb +46 -0
- data/lib/oxidized/model/gaiaos.rb +4 -4
- data/lib/oxidized/model/garderos.rb +38 -0
- data/lib/oxidized/model/grandstreamht8xx.rb +19 -0
- data/lib/oxidized/model/h3c.rb +1 -1
- data/lib/oxidized/model/ibos.rb +1 -0
- data/lib/oxidized/model/ingate.rb +47 -0
- data/lib/oxidized/model/ios.rb +57 -30
- data/lib/oxidized/model/iosxr.rb +2 -2
- data/lib/oxidized/model/ironware.rb +7 -5
- data/lib/oxidized/model/ivanti.rb +54 -0
- data/lib/oxidized/model/junos.rb +12 -5
- data/lib/oxidized/model/kornfeldos.rb +33 -0
- data/lib/oxidized/model/lenovonos.rb +2 -0
- data/lib/oxidized/model/linksyssrw.rb +3 -3
- data/lib/oxidized/model/linuxgeneric.rb +4 -2
- data/lib/oxidized/model/macros.rb +60 -0
- data/lib/oxidized/model/mimosab11.rb +34 -0
- data/lib/oxidized/model/ml66.rb +33 -0
- data/lib/oxidized/model/mlnxos.rb +18 -14
- data/lib/oxidized/model/model.rb +98 -103
- data/lib/oxidized/model/mtrlrfs.rb +1 -0
- data/lib/oxidized/model/ndms.rb +6 -0
- data/lib/oxidized/model/netgear.rb +14 -3
- data/lib/oxidized/model/netonix.rb +1 -1
- data/lib/oxidized/model/netscaler.rb +1 -1
- data/lib/oxidized/model/nodegrid.rb +1 -1
- data/lib/oxidized/model/nsxdfw.rb +31 -0
- data/lib/oxidized/model/nsxfirewall.rb +2 -1
- data/lib/oxidized/model/nxos.rb +20 -15
- data/lib/oxidized/model/ocnos.rb +42 -0
- data/lib/oxidized/model/onefinity.rb +18 -0
- data/lib/oxidized/model/openbsd.rb +1 -1
- data/lib/oxidized/model/opengear.rb +36 -1
- data/lib/oxidized/model/openwrt.rb +6 -6
- data/lib/oxidized/model/opnsense.rb +9 -1
- data/lib/oxidized/model/os6.rb +48 -0
- data/lib/oxidized/model/outputs.rb +5 -0
- data/lib/oxidized/model/panos.rb +2 -0
- data/lib/oxidized/model/perle.rb +41 -0
- data/lib/oxidized/model/pfsense.rb +9 -0
- data/lib/oxidized/model/powerconnect.rb +32 -11
- data/lib/oxidized/model/procurve.rb +6 -2
- data/lib/oxidized/model/qtech.rb +3 -1
- data/lib/oxidized/model/quantaos.rb +8 -6
- data/lib/oxidized/model/rgos.rb +33 -0
- data/lib/oxidized/model/riverbed.rb +104 -0
- data/lib/oxidized/model/routeros.rb +18 -11
- data/lib/oxidized/model/saos.rb +18 -1
- data/lib/oxidized/model/saos10.rb +38 -0
- data/lib/oxidized/model/siklu.rb +1 -1
- data/lib/oxidized/model/siklumhtg.rb +22 -0
- data/lib/oxidized/model/sixwind.rb +28 -0
- data/lib/oxidized/model/slxos.rb +3 -3
- data/lib/oxidized/model/smartbyte.rb +48 -0
- data/lib/oxidized/model/sonicos.rb +27 -20
- data/lib/oxidized/model/speedtouch.rb +1 -1
- data/lib/oxidized/model/sros.rb +3 -3
- data/lib/oxidized/model/srosmd.rb +1 -1
- data/lib/oxidized/model/supermicro.rb +1 -1
- data/lib/oxidized/model/telco.rb +1 -1
- data/lib/oxidized/model/tmos.rb +1 -0
- data/lib/oxidized/model/tnsr.rb +57 -0
- data/lib/oxidized/model/tplink.rb +5 -5
- data/lib/oxidized/model/trango.rb +4 -2
- data/lib/oxidized/model/truenas.rb +64 -3
- data/lib/oxidized/model/ucs.rb +1 -1
- data/lib/oxidized/model/unifiap.rb +144 -0
- data/lib/oxidized/model/uplinkolt.rb +46 -0
- data/lib/oxidized/model/voltaire.rb +1 -1
- data/lib/oxidized/model/voss.rb +3 -0
- data/lib/oxidized/model/vrp.rb +5 -1
- data/lib/oxidized/model/vyatta.rb +9 -3
- data/lib/oxidized/model/vyos.rb +37 -0
- data/lib/oxidized/model/xos.rb +10 -1
- data/lib/oxidized/model/zhoneolt.rb +4 -2
- data/lib/oxidized/model/zynos.rb +67 -3
- data/lib/oxidized/model/zynosadsl.rb +14 -0
- data/lib/oxidized/model/zynoscli.rb +1 -1
- data/lib/oxidized/model/zynosgs.rb +2 -0
- data/lib/oxidized/model/zynosmgs.rb +32 -0
- data/lib/oxidized/node.rb +99 -64
- data/lib/oxidized/nodes.rb +40 -19
- data/lib/oxidized/output/file.rb +80 -43
- data/lib/oxidized/output/git.rb +295 -151
- data/lib/oxidized/output/gitcrypt.rb +193 -185
- data/lib/oxidized/output/http.rb +63 -51
- data/lib/oxidized/output/output.rb +20 -4
- data/lib/oxidized/signals.rb +44 -0
- data/lib/oxidized/source/csv.rb +49 -49
- data/lib/oxidized/source/http.rb +76 -63
- data/lib/oxidized/source/jsonfile.rb +68 -0
- data/lib/oxidized/source/source.rb +73 -18
- data/lib/oxidized/source/sql.rb +71 -59
- data/lib/oxidized/version.rb +6 -4
- data/lib/oxidized/worker.rb +57 -29
- data/lib/oxidized.rb +4 -24
- data/lib/refinements.rb +21 -1
- data/oxidized.gemspec +45 -21
- metadata +248 -41
- data/lib/oxidized/model/timos.rb +0 -10
data/docs/Configuration.md
CHANGED
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
# Configuration
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```yaml
|
|
10
|
-
log: /home/oxidized/.config/oxidized/log
|
|
11
|
-
|
|
12
|
-
...
|
|
13
|
-
|
|
14
|
-
input:
|
|
15
|
-
default: ssh, telnet
|
|
16
|
-
debug: true
|
|
17
|
-
ssh:
|
|
18
|
-
secure: false
|
|
19
|
-
http:
|
|
20
|
-
ssl_verify: true
|
|
21
|
-
```
|
|
3
|
+
## Modules
|
|
4
|
+
The configuration of each module is described in its respective sub-configuration file:
|
|
5
|
+
* [Inputs.md](Inputs.md)
|
|
6
|
+
* [Outputs.md](Outputs.md)
|
|
7
|
+
* [Sources.md](Sources.md)
|
|
8
|
+
* [Hooks.md](Hooks.md)
|
|
22
9
|
|
|
23
10
|
## Privileged mode
|
|
24
11
|
|
|
25
|
-
To start privileged mode before pulling the configuration, Oxidized needs to
|
|
12
|
+
To start privileged mode before pulling the configuration, Oxidized needs to
|
|
13
|
+
send the enable command. You can globally enable this, by adding the following
|
|
14
|
+
snippet to the global section of the configuration file.
|
|
26
15
|
|
|
27
16
|
```yaml
|
|
28
17
|
vars:
|
|
@@ -31,21 +20,24 @@ vars:
|
|
|
31
20
|
|
|
32
21
|
## Removing secrets
|
|
33
22
|
|
|
34
|
-
To strip out secrets from configurations before storing them, Oxidized needs the
|
|
23
|
+
To strip out secrets from configurations before storing them, Oxidized needs the
|
|
24
|
+
`remove_secret` flag. You can globally enable this by adding the following
|
|
25
|
+
snippet to the global section of the configuration file.
|
|
35
26
|
|
|
36
27
|
```yaml
|
|
37
28
|
vars:
|
|
38
29
|
remove_secret: true
|
|
39
30
|
```
|
|
40
31
|
|
|
41
|
-
Device models that contain substitution filters to remove sensitive data will
|
|
32
|
+
Device models that contain substitution filters to remove sensitive data will
|
|
33
|
+
now be run on any fetched configuration.
|
|
42
34
|
|
|
43
35
|
As a partial example from ios.rb:
|
|
44
36
|
|
|
45
37
|
```ruby
|
|
46
38
|
cmd :secret do |cfg|
|
|
47
39
|
cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
|
|
48
|
-
|
|
40
|
+
# ...
|
|
49
41
|
cfg
|
|
50
42
|
end
|
|
51
43
|
```
|
|
@@ -54,135 +46,43 @@ The above strips out snmp community strings from your saved configs.
|
|
|
54
46
|
|
|
55
47
|
**NOTE:** Removing secrets reduces the usefulness as a full configuration backup, but it may make sharing configs easier.
|
|
56
48
|
|
|
57
|
-
##
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```yaml
|
|
63
|
-
vars:
|
|
64
|
-
ssh_no_exec: true
|
|
65
|
-
```
|
|
49
|
+
## Timeout and Time limit
|
|
50
|
+
You can configure when oxidized will `timeout` while fetching a configuration
|
|
51
|
+
(default: 20 seconds), and how much absolute time (`timelimit`) the fetching
|
|
52
|
+
is allowed to last (default: 300 seconds, or 5 minutes):
|
|
66
53
|
|
|
67
|
-
|
|
54
|
+
* `timeout`: Maximum time to wait for a single operation during config fetching.
|
|
55
|
+
Not every input module has an implemented timeout.
|
|
56
|
+
* `timelimit`: Maximum total time allowed for the entire fetch job. It is
|
|
57
|
+
independent of input modules and will always be enforced.
|
|
68
58
|
|
|
69
|
-
|
|
59
|
+
If `timelimit`is reached, the fetch job will be killed and will produce a
|
|
60
|
+
warning. The job status will be set to `timelimit`.
|
|
70
61
|
|
|
71
62
|
```yaml
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## SSH Auth Methods
|
|
77
|
-
|
|
78
|
-
By default, Oxidized registers the following auth methods: `none`, `publickey` and `password`. However you can configure this globally, by groups, models or nodes.
|
|
79
|
-
|
|
80
|
-
```yaml
|
|
81
|
-
vars:
|
|
82
|
-
auth_methods: [ "none", "publickey", "password", "keyboard-interactive" ]
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Public Key Authentication with SSH
|
|
86
|
-
|
|
87
|
-
Instead of password-based login, Oxidized can make use of key-based SSH authentication.
|
|
88
|
-
|
|
89
|
-
You can tell Oxidized to use one or more private keys globally, or specify the key to be used on a per-node basis. The latter can be done by mapping the `ssh_keys` variable through the active source.
|
|
90
|
-
|
|
91
|
-
Global:
|
|
92
|
-
|
|
93
|
-
```yaml
|
|
94
|
-
vars:
|
|
95
|
-
ssh_keys: "~/.ssh/id_rsa"
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Per-Node:
|
|
99
|
-
|
|
100
|
-
```yaml
|
|
101
|
-
...
|
|
102
|
-
map:
|
|
103
|
-
name: 0
|
|
104
|
-
model: 1
|
|
105
|
-
vars_map:
|
|
106
|
-
enable: 2
|
|
107
|
-
ssh_keys: 3
|
|
108
|
-
...
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
If you are using a non-standard path, especially when copying the private key via a secured channel, make sure that the permissions are set correctly:
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
foo@bar:~$ ls -la ~/.ssh/
|
|
115
|
-
total 20
|
|
116
|
-
drwx------ 2 oxidized oxidized 4096 Mar 13 17:03 .
|
|
117
|
-
drwx------ 5 oxidized oxidized 4096 Mar 13 21:40 ..
|
|
118
|
-
-r-------- 1 oxidized oxidized 103 Mar 13 17:03 authorized_keys
|
|
119
|
-
-rw------- 1 oxidized oxidized 399 Mar 13 17:02 id_ed25519
|
|
120
|
-
-rw-r--r-- 1 oxidized oxidized 94 Mar 13 17:02 id_ed25519.pub
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Finally, multiple private keys can be specified as an array of file paths, such as `["~/.ssh/id_rsa", "~/.ssh/id_another_rsa"]`.
|
|
124
|
-
|
|
125
|
-
## SSH Proxy Command
|
|
126
|
-
|
|
127
|
-
Oxidized can `ssh` through a proxy as well. To do so we just need to set `ssh_proxy` variable with the proxy host information and optionally set the `ssh_proxy_port` with the SSH port if it is not listening on port 22.
|
|
128
|
-
|
|
129
|
-
This can be provided on a per-node basis by mapping the proper fields from your source.
|
|
130
|
-
|
|
131
|
-
An example for a `csv` input source that maps the 4th field as the `ssh_proxy` value and the 5th field as `ssh_proxy_port`.
|
|
132
|
-
|
|
133
|
-
```yaml
|
|
134
|
-
...
|
|
135
|
-
map:
|
|
136
|
-
name: 0
|
|
137
|
-
model: 1
|
|
138
|
-
vars_map:
|
|
139
|
-
enable: 2
|
|
140
|
-
ssh_proxy: 3
|
|
141
|
-
ssh_proxy_port: 4
|
|
142
|
-
...
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## SSH enabling legacy algorithms
|
|
146
|
-
|
|
147
|
-
When connecting to older firmware over SSH, it is sometimes necessary to enable legacy/disabled settings like KexAlgorithms, HostKeyAlgorithms, MAC or the Encryption.
|
|
148
|
-
|
|
149
|
-
These settings can be provided on a per-node basis by mapping the ssh_kex, ssh_host_key, ssh_hmac and the ssh_encryption fields from you source.
|
|
150
|
-
|
|
151
|
-
```yaml
|
|
152
|
-
...
|
|
153
|
-
map:
|
|
154
|
-
name: 0
|
|
155
|
-
model: 1
|
|
156
|
-
vars_map:
|
|
157
|
-
enable: 2
|
|
158
|
-
ssh_kex: 3
|
|
159
|
-
ssh_host_key: 4
|
|
160
|
-
ssh_hmac: 5
|
|
161
|
-
ssh_encryption: 6
|
|
162
|
-
...
|
|
63
|
+
timeout: 20
|
|
64
|
+
timelimit: 300
|
|
163
65
|
```
|
|
164
66
|
|
|
165
|
-
##
|
|
67
|
+
## Advanced Configuration
|
|
166
68
|
|
|
167
|
-
|
|
69
|
+
Below is an advanced example configuration.
|
|
168
70
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
```
|
|
71
|
+
You will be able to (optionally) override options per device.
|
|
72
|
+
The router.db format used is `hostname:model:username:password:enable_password`.
|
|
73
|
+
Hostname and model will be the only required options, all others override the
|
|
74
|
+
global configuration sections.
|
|
174
75
|
|
|
175
|
-
|
|
76
|
+
Custom model names can be mapped to an oxidized model name with a string or
|
|
77
|
+
a regular expression.
|
|
176
78
|
|
|
177
|
-
Below is an advanced example configuration. You will be able to (optionally) override options per device. The router.db format used is `hostname:model:username:password:enable_password`. Hostname and model will be the only required options, all others override the global configuration sections.
|
|
178
79
|
|
|
179
80
|
```yaml
|
|
180
81
|
---
|
|
181
82
|
username: oxidized
|
|
182
83
|
password: S3cr3tx
|
|
183
84
|
model: junos
|
|
184
|
-
interval: 3600 #interval in seconds
|
|
185
|
-
log: ~/.config/oxidized/log
|
|
85
|
+
interval: 3600 #interval in seconds, when 0 is configured no fetch config is done at initial start and after
|
|
186
86
|
debug: false
|
|
187
87
|
threads: 30 # maximum number of threads
|
|
188
88
|
# use_max_threads:
|
|
@@ -190,6 +90,7 @@ threads: 30 # maximum number of threads
|
|
|
190
90
|
# true - always use the maximum number of threads
|
|
191
91
|
use_max_threads: false
|
|
192
92
|
timeout: 20
|
|
93
|
+
timelimit: 300
|
|
193
94
|
retries: 3
|
|
194
95
|
prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
|
|
195
96
|
crash:
|
|
@@ -198,7 +99,21 @@ crash:
|
|
|
198
99
|
vars:
|
|
199
100
|
enable: S3cr3tx
|
|
200
101
|
groups: {}
|
|
201
|
-
|
|
102
|
+
extensions:
|
|
103
|
+
oxidized-web:
|
|
104
|
+
load: true
|
|
105
|
+
# Bind to any IPv4 interface
|
|
106
|
+
listen: 0.0.0.0
|
|
107
|
+
# Bind to port 8888 (default)
|
|
108
|
+
port: 8888
|
|
109
|
+
# Prefix prod to the URL, so http://oxidized.full.domain/prod/
|
|
110
|
+
url_prefix: prod
|
|
111
|
+
# virtual hosts to listen to (others will be denied)
|
|
112
|
+
vhosts:
|
|
113
|
+
- localhost
|
|
114
|
+
- 127.0.0.1
|
|
115
|
+
- oxidized
|
|
116
|
+
- oxidized.full.domain
|
|
202
117
|
pid: ~/.config/oxidized/oxidized.pid
|
|
203
118
|
input:
|
|
204
119
|
default: ssh, telnet
|
|
@@ -226,6 +141,17 @@ source:
|
|
|
226
141
|
model_map:
|
|
227
142
|
cisco: ios
|
|
228
143
|
juniper: junos
|
|
144
|
+
!ruby/regexp /procurve/: procurve
|
|
145
|
+
logger:
|
|
146
|
+
# The default level is :info
|
|
147
|
+
# level: :info
|
|
148
|
+
appenders:
|
|
149
|
+
- type: syslog
|
|
150
|
+
level: :error
|
|
151
|
+
- type: stdout
|
|
152
|
+
level: :warn
|
|
153
|
+
- type: file
|
|
154
|
+
file: ~/.config/oxidized/info.log
|
|
229
155
|
```
|
|
230
156
|
|
|
231
157
|
## Advanced Group Configuration
|
|
@@ -242,13 +168,15 @@ groups:
|
|
|
242
168
|
password: ubnt
|
|
243
169
|
```
|
|
244
170
|
|
|
245
|
-
Model specific variables within groups
|
|
171
|
+
Model specific variables/credentials within groups
|
|
246
172
|
|
|
247
173
|
```yaml
|
|
248
174
|
groups:
|
|
249
175
|
foo:
|
|
250
176
|
models:
|
|
251
177
|
arista:
|
|
178
|
+
username: admin
|
|
179
|
+
password: password
|
|
252
180
|
vars:
|
|
253
181
|
ssh_keys: "~/.ssh/id_rsa_foo_arista"
|
|
254
182
|
vyatta:
|
|
@@ -260,11 +188,14 @@ groups:
|
|
|
260
188
|
vars:
|
|
261
189
|
ssh_keys: "~/.ssh/id_rsa_bar_routeros"
|
|
262
190
|
vyatta:
|
|
191
|
+
username: admin
|
|
192
|
+
password: pass
|
|
263
193
|
vars:
|
|
264
194
|
ssh_keys: "~/.ssh/id_rsa_bar_vyatta"
|
|
265
195
|
```
|
|
266
196
|
|
|
267
|
-
For mapping multiple group values to a common name
|
|
197
|
+
For mapping multiple group values to a common name, you can use strings and
|
|
198
|
+
regular expressions:
|
|
268
199
|
|
|
269
200
|
```yaml
|
|
270
201
|
group_map:
|
|
@@ -272,17 +203,18 @@ group_map:
|
|
|
272
203
|
alias2: groupA
|
|
273
204
|
alias3: groupB
|
|
274
205
|
alias4: groupB
|
|
206
|
+
!ruby/regexp /specialgroup/: groupS
|
|
275
207
|
aliasN: groupZ
|
|
276
|
-
...
|
|
208
|
+
# ...
|
|
277
209
|
```
|
|
278
210
|
|
|
279
211
|
add group mapping to a source
|
|
280
212
|
|
|
281
213
|
```yaml
|
|
282
214
|
source:
|
|
283
|
-
...
|
|
215
|
+
# ...
|
|
284
216
|
<source>:
|
|
285
|
-
...
|
|
217
|
+
# ...
|
|
286
218
|
map:
|
|
287
219
|
model: 0
|
|
288
220
|
name: 1
|
|
@@ -311,25 +243,109 @@ models:
|
|
|
311
243
|
password: pass
|
|
312
244
|
```
|
|
313
245
|
|
|
314
|
-
##
|
|
246
|
+
## Options (credentials, vars, etc.) precedence:
|
|
247
|
+
From least to most important:
|
|
248
|
+
- global options
|
|
249
|
+
- model specific options
|
|
250
|
+
- group specific options
|
|
251
|
+
- model specific options in groups
|
|
252
|
+
- options defined on single nodes
|
|
253
|
+
|
|
254
|
+
More important options overwrite less important ones if they are set.
|
|
255
|
+
|
|
256
|
+
## oxidized-web: RESTful API and web interface
|
|
257
|
+
|
|
258
|
+
The RESTful API and web interface are enabled by installing the `oxidized-web`
|
|
259
|
+
gem and configuring the `extensions.oxidized-web:` section in the configuration
|
|
260
|
+
file. You can set the following parameter:
|
|
261
|
+
- `load`: `true`/`false`: Enables or disables the `oxidized-web` extension
|
|
262
|
+
(default: `false`)
|
|
263
|
+
- `listen`: Specifies the interface to bind to (default: `127.0.0.1`). Valid
|
|
264
|
+
options:
|
|
265
|
+
- `127.0.0.1`: Allows IPv4 connections from localhost only
|
|
266
|
+
- `'[::1]'`: Allows IPv6 connections from localhost only
|
|
267
|
+
- `<IPv4-Address>` or `'[<IPv6-Address>]'`: Binds to a specific interface
|
|
268
|
+
- `0.0.0.0`: Binds to any IPv4 interface
|
|
269
|
+
- `'[::]'`: Binds to any IPv4 and IPv6 interface
|
|
270
|
+
- `port`: Specifies the TCP port to listen to (default: `8888`)
|
|
271
|
+
- `url_prefix`: Defines a URL prefix (default: no prefix)
|
|
272
|
+
- `vhosts`: A list of virtual hosts to listen to. If not specified, it will
|
|
273
|
+
respond to any virtual host.
|
|
274
|
+
|
|
275
|
+
> [!NOTE]
|
|
276
|
+
> The old syntax `rest: 127.0.0.1:8888/prefix` is still supported but
|
|
277
|
+
> deprecated. It produces a warning and won't be suported in future releases.
|
|
278
|
+
>
|
|
279
|
+
> If the `rest` configuration is used, the extensions.oxidized-web will be
|
|
280
|
+
> ignored.
|
|
281
|
+
|
|
282
|
+
> [!NOTE]
|
|
283
|
+
> You need oxidized-web version 0.16.0 or later to use the
|
|
284
|
+
> extentions.oxidized-web configuration
|
|
285
|
+
|
|
315
286
|
|
|
316
|
-
|
|
287
|
+
```yaml
|
|
288
|
+
# Listen on http://[::1]:8888/
|
|
289
|
+
extensions:
|
|
290
|
+
oxidized-web:
|
|
291
|
+
load: true
|
|
292
|
+
listen: '[::1]'
|
|
293
|
+
port: 8888
|
|
294
|
+
```
|
|
317
295
|
|
|
318
296
|
```yaml
|
|
319
297
|
# Listen on http://127.0.0.1:8888/
|
|
320
|
-
|
|
298
|
+
extensions:
|
|
299
|
+
oxidized-web:
|
|
300
|
+
load: true
|
|
301
|
+
listen: 127.0.0.1
|
|
302
|
+
port: 8888
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
# Listen on http://[2001:db8:0:face:b001:0:dead:beaf]:8888/oxidized/
|
|
307
|
+
extensions:
|
|
308
|
+
oxidized-web:
|
|
309
|
+
load: true
|
|
310
|
+
listen: '[2001:db8:0:face:b001:0:dead:beaf]'
|
|
311
|
+
port: 8888
|
|
312
|
+
url_prefix: oxidized
|
|
321
313
|
```
|
|
322
314
|
|
|
323
315
|
```yaml
|
|
324
316
|
# Listen on http://10.0.0.1:8000/oxidized/
|
|
325
|
-
|
|
317
|
+
extensions:
|
|
318
|
+
oxidized-web:
|
|
319
|
+
load: true
|
|
320
|
+
listen: 10.0.0.1
|
|
321
|
+
port: 8000
|
|
322
|
+
url_prefix: oxidized
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
```yaml
|
|
326
|
+
# Listen on any interface to http://oxidized.rocks:8888 and
|
|
327
|
+
# http://oxidized:8888
|
|
328
|
+
extensions:
|
|
329
|
+
oxidized-web:
|
|
330
|
+
load: true
|
|
331
|
+
listen: '[::]'
|
|
332
|
+
url_prefix: oxidized
|
|
333
|
+
vhosts:
|
|
334
|
+
- oxidized.rocks
|
|
335
|
+
- oxidized
|
|
326
336
|
```
|
|
327
337
|
|
|
328
338
|
## Triggered backups
|
|
329
339
|
|
|
330
|
-
A node can be moved to head-of-queue via the REST API `GET/
|
|
340
|
+
A node can be moved to head-of-queue via the REST API `GET/PUT
|
|
341
|
+
/node/next/[NODE]`. This can be useful to immediately schedule a fetch of the
|
|
342
|
+
configuration after some other event such as a syslog message indicating a
|
|
343
|
+
configuration update on the device.
|
|
331
344
|
|
|
332
|
-
In the default configuration this node will be processed when the next job
|
|
345
|
+
In the default configuration this node will be processed when the next job
|
|
346
|
+
worker becomes available, it could take some time if existing backups are in
|
|
347
|
+
progress. To execute moved jobs immediately a new job can be added
|
|
348
|
+
automatically:
|
|
333
349
|
|
|
334
350
|
```yaml
|
|
335
351
|
next_adds_job: true
|
|
@@ -339,7 +355,10 @@ This will allow for a more timely fetch of the device configuration.
|
|
|
339
355
|
|
|
340
356
|
## Disabling DNS resolution
|
|
341
357
|
|
|
342
|
-
In some instances it might not be desirable to attempt to resolve names of
|
|
358
|
+
In some instances it might not be desirable to attempt to resolve names of
|
|
359
|
+
nodes. One such use case is when nodes are accessed through an SSH proxy, where
|
|
360
|
+
the remote end resolves the names differently than the host on which Oxidized
|
|
361
|
+
runs would.
|
|
343
362
|
|
|
344
363
|
Names can instead be passed verbatim to the input:
|
|
345
364
|
|
|
@@ -353,3 +372,217 @@ You can use some environment variables to change default root directories values
|
|
|
353
372
|
|
|
354
373
|
* `OXIDIZED_HOME` may be used to set oxidized configuration directory, which defaults to `~/.config/oxidized`
|
|
355
374
|
* `OXIDIZED_LOGS` may be used to set oxidzied logs and crash directories root, which default to `~/.config/oxidized`
|
|
375
|
+
|
|
376
|
+
## Logging
|
|
377
|
+
Oxidized supports parallel logging to different systems (appenders). The
|
|
378
|
+
following appenders are currently supported:
|
|
379
|
+
- `stderr`: log to standard error (this is the default)
|
|
380
|
+
- `stdout`: log to standard output
|
|
381
|
+
- `file`: log to a file
|
|
382
|
+
- `syslog`: log to syslog
|
|
383
|
+
|
|
384
|
+
> `stderr` and `stdout` are mutually exclusive and will produce a warning if used
|
|
385
|
+
> simultaneously.
|
|
386
|
+
|
|
387
|
+
> You can configure as many file appenders as you wish.
|
|
388
|
+
|
|
389
|
+
You can set a log level globally and/or for each appender.
|
|
390
|
+
- The global log level will limit which log messages are accepted, depending
|
|
391
|
+
on their level.
|
|
392
|
+
- The default global log level is `:info`.
|
|
393
|
+
- If you set `debug: true` in the configuration, the global log level will be
|
|
394
|
+
forced to `:debug`.
|
|
395
|
+
- The appender log level limits which log messages are displayed by the
|
|
396
|
+
appender, depending on their level.
|
|
397
|
+
- The default is `:trace`.
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
> Available log levels: `:trace`, `:debug`, `:info`, `:warn`,
|
|
401
|
+
> `:error` and `:fatal`
|
|
402
|
+
|
|
403
|
+
Here is a configuration example logging `:error` to syslog, `:warn` to stdout
|
|
404
|
+
and `:info` to `~/.config/oxidized/info.log`:
|
|
405
|
+
|
|
406
|
+
```yaml
|
|
407
|
+
logger:
|
|
408
|
+
# Default level
|
|
409
|
+
# level: :info
|
|
410
|
+
appenders:
|
|
411
|
+
- type: syslog
|
|
412
|
+
level: :error
|
|
413
|
+
- type: stdout
|
|
414
|
+
level: :warn
|
|
415
|
+
- type: file
|
|
416
|
+
# Default level is :trace, so we get the logs in the default level (:info)
|
|
417
|
+
file: ~/.config/oxidized/info.log
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
If you want to log :trace to a file and `:info` to stdout, you must set the
|
|
421
|
+
global log level to `:trace`, and limit the stdout appender to `:info`:
|
|
422
|
+
|
|
423
|
+
```yaml
|
|
424
|
+
logger:
|
|
425
|
+
level: :trace
|
|
426
|
+
appenders:
|
|
427
|
+
- type: stdout
|
|
428
|
+
level: :info
|
|
429
|
+
- type: file
|
|
430
|
+
file: ~/.config/oxidized/trace.log
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Change log level
|
|
434
|
+
You can change the global log level of oxidized by sending a SIGUSR2 to
|
|
435
|
+
the process:
|
|
436
|
+
```
|
|
437
|
+
kill -SIGUSR2 424242
|
|
438
|
+
```
|
|
439
|
+
It will rotate between the log levels and log a warning with the new level
|
|
440
|
+
(you won't see the warning when the log level is `:fatal` or `:error`):
|
|
441
|
+
```
|
|
442
|
+
2025-06-30 15:25:27.972881 W [109750:2640] SemanticLogger -- Changed global default log level to :warn
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
If you specified a log level for an appender, this log level won't be
|
|
446
|
+
changed.
|
|
447
|
+
|
|
448
|
+
> :warning: **Warning** You need oxidized-web 0.17.0 and above for this or
|
|
449
|
+
> it will kill the whole oxidized application.
|
|
450
|
+
|
|
451
|
+
### Dump running threads
|
|
452
|
+
With the SIGTTIN signal, oxidized will log a backtrace for each of its threads.
|
|
453
|
+
```
|
|
454
|
+
kill -SIGTTIN 424242
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
The threads used to fetch the configs are named `Oxidized::Job 'hostname'`:
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
2025-06-30 15:32:22.293047 W [110549:2640 core.rb:76] Thread Dump -- Backtrace:
|
|
461
|
+
/home/xxx/oxidized/lib/oxidized/core.rb:76:in `sleep'
|
|
462
|
+
/home/xxx/oxidized/lib/oxidized/core.rb:76:in `block in run'
|
|
463
|
+
(...)
|
|
464
|
+
2025-06-30 15:32:22.293409 W [110549:Oxidized::Job 'host2' ssh.rb:127] Thread Dump -- Backtrace:
|
|
465
|
+
/home/xxx/oxidized/lib/oxidized/input/ssh.rb:127:in `sleep'
|
|
466
|
+
/home/xxx/oxidized/lib/oxidized/input/ssh.rb:127:in `block (2 levels) in expect'
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Metadata
|
|
470
|
+
You can include some metadata in your model outputs, for this you have to set
|
|
471
|
+
the variable `metadata` to `true`:
|
|
472
|
+
```yaml
|
|
473
|
+
vars:
|
|
474
|
+
metadata: true
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
As every [variable](#options-credentials-vars-etc-precedence), you can set it on
|
|
478
|
+
model, group and even node level.
|
|
479
|
+
|
|
480
|
+
By default this will produce
|
|
481
|
+
`"%{comment}Fetched by Oxidized with model %{model} from host %{name} [%{ip}]\n"`
|
|
482
|
+
at the first line of every model output. Some models with specific needs (XML
|
|
483
|
+
for example) will save the metadata differently (for example, OpnSense and
|
|
484
|
+
PfSense save an XML comment at the end of the model).
|
|
485
|
+
|
|
486
|
+
### Customize metadata
|
|
487
|
+
You can customize the metadata produced by setting the varibles `metadata_top`
|
|
488
|
+
(top of the file) and `metadata_bottom` (bottom of the file).
|
|
489
|
+
|
|
490
|
+
These variables accept string templates, and you can include newline characters
|
|
491
|
+
(\n) to control formatting.
|
|
492
|
+
|
|
493
|
+
Both `metadata_top` and `metadata_bottom` support interpolation of dynamic values
|
|
494
|
+
using the following substitution templates:
|
|
495
|
+
- `%{model}`: name of the Oxidized model
|
|
496
|
+
- `%{name}`: name of the node
|
|
497
|
+
- `%{ip}`: IP address of the node
|
|
498
|
+
- `%{group}`: group name of the node
|
|
499
|
+
- `%{comment}`: comment string used in the model output (`# `)
|
|
500
|
+
- `%{year}`: current year (`2025`)
|
|
501
|
+
- `%{month}`: current month, zero-padded (`03` for March)
|
|
502
|
+
- `%{day}`: current day, zero-padded (`09`)
|
|
503
|
+
- `%{hour}`: current hour (24-hour format, zero-padded)
|
|
504
|
+
- `%{minute}`: current minute, zero-padded
|
|
505
|
+
- `%{second}`: current second, zero-padded
|
|
506
|
+
|
|
507
|
+
Example:
|
|
508
|
+
```yaml
|
|
509
|
+
vars:
|
|
510
|
+
metadata: true
|
|
511
|
+
metadata_top: "%{comment}Model: %{model}; Device %{name} [%{ip}] at %{year}-%{month}-%{day} %{hour}:%{minute}:%{second}\n"
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Customize metadata in models
|
|
515
|
+
When writing a custom metadata for a model, you can default to
|
|
516
|
+
`vars("metadata_*")` or the model default. You need to interpolate the strings
|
|
517
|
+
with interpolate_string. This example is taken from OpnSense, and makes an
|
|
518
|
+
XML comment of the default strings, with precedence for vars("metadata_bottom"),
|
|
519
|
+
as the XML comment is situated at the bottom.
|
|
520
|
+
|
|
521
|
+
```ruby
|
|
522
|
+
metadata :bottom do
|
|
523
|
+
xmlcomment interpolate_string(
|
|
524
|
+
vars("metadata_bottom") ||
|
|
525
|
+
vars("metadata_top") ||
|
|
526
|
+
Oxidized::Model::METADATA_DEFAULT
|
|
527
|
+
)
|
|
528
|
+
end
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
You can also change the metadata in the models in your configuration directory with
|
|
532
|
+
[monkey patching](Creating-Models.md#monkey-patching-blocks-in-existing-models).
|
|
533
|
+
This can be done in two ways:
|
|
534
|
+
|
|
535
|
+
1. Interpolation string:
|
|
536
|
+
```ruby
|
|
537
|
+
require 'oxidized/model/ios.rb'
|
|
538
|
+
|
|
539
|
+
class IOS
|
|
540
|
+
metadata :top, "%{comment}Model: %{model}\n"
|
|
541
|
+
metadata :bottom, "%{comment}Will be placed at the end of the output\n"
|
|
542
|
+
end
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
2. For advanced code, you can use a code block, and access every variable of
|
|
546
|
+
the model:
|
|
547
|
+
|
|
548
|
+
```ruby
|
|
549
|
+
require 'oxidized/model/opnsense.rb'
|
|
550
|
+
class OpnSense
|
|
551
|
+
metadata :top do
|
|
552
|
+
xmlcomment "Model:#{self.class.name}, hostname: #{@node.name}, ip:#{@node.ip}"
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
metadata :bottom, nil
|
|
556
|
+
end
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
Remove a previous metadata by setting it to `nil`.
|
|
560
|
+
|
|
561
|
+
## Store configuration only on significant changes
|
|
562
|
+
Some devices produce configuration changes even though nothing relevant
|
|
563
|
+
changed. For example, Cisco IOS produces a `Last configuration change at` as
|
|
564
|
+
soon as you exit config mode, and FortiOS encrypts its passwords with a
|
|
565
|
+
different salt on every run.
|
|
566
|
+
|
|
567
|
+
By setting the [variable](#options-credentials-vars-etc-precedence)
|
|
568
|
+
`output_store_mode` to `on_significant`, you can tell Oxidized only to
|
|
569
|
+
store the configuration when significant changes occurred. The default is to
|
|
570
|
+
always store the configuration.
|
|
571
|
+
```yaml
|
|
572
|
+
vars:
|
|
573
|
+
output_store_mode: on_significant
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
For this to work, the model must implement `cmd :significant_changes`:
|
|
577
|
+
```ruby
|
|
578
|
+
cmd :significant_changes do |cfg|
|
|
579
|
+
cfg.reject_lines [
|
|
580
|
+
'Last configuration change at',
|
|
581
|
+
'NVRAM config last updated at'
|
|
582
|
+
]
|
|
583
|
+
end
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
Note that store on significant change only applies to the main configuration,
|
|
587
|
+
and will not affect
|
|
588
|
+
[output types](Creating-Models.md#advanced-feature-output-type)
|